promotional bannermobile promotional banner

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.
Back to Files

BlockProtReloaded-1.3.5

File nameBlockProtReloaded-1.3.5.jar
Uploader
ZaynrZarZaynrZar
Uploaded
Aug 28, 2026
Downloads
5
Size
5.8 MB
File ID
8751107
Type
R
Release
Supported game versions
  • 26.2
  • 26.1.2
  • 26.1.1
  • 26.1
  • 1.21.11
  • 1.21.10
  • 1.21.9
  • 1.21.8
  • 1.21.7
  • 1.21.6
  • 1.21.5
  • 1.21.4
  • 1.21.3
  • 1.21.2
  • 1.21.1

What's new

1.3.5

Summary

This release completes the admin config editor story started in 1.3.4. The dialog-based editor already mirrored config.yml section by section; 1.3.5 adds the matching inventory-based editor for servers running use_dialogs: false, so the Config entry in the Admin Menu now opens a real editor on every server software instead of the "not available" message dialog-mode servers never saw.

1.3.5 also closes the last remaining gap between the dialog and inventory UIs: per-world lockables selection, previously an inventory-only feature, now has its dialog counterpart (/bp lockables > Configure per world), so the lockables system is fully reachable from both interfaces.

On the dialog side, this release is mostly internal quality-of-life: AdminConfigDialog was split from one 826-line class into one class per category, the duplicated back-button switches in 16 dialog screens were replaced by a single unified helper, a per-player back stack makes BlockLock sub-screens return to the exact block lock screen they came from, and the category selector dialog gained a Reload button for parity with the inventory selector. The one remaining hardcoded English string in the reload flow (the failure message) was moved to a translation key. The six pastel dialog colors and the color-code stripping helper, duplicated verbatim in 18 dialog classes, were centralized into one shared BpDialogStyles class.

The dialog and inventory editors are interchangeable: same categories, same settings, same order, same labels, same config keys, same values, same click behavior. Both write through the same save path (setAndSave, the same suppress-then-reload invariant a manual YAML edit follows), and both validate numeric input with the same in-chat error message.

Inventory Config Editor

/bp admin > Config now routes per player preference:

  • On a Paper 1.21.7+ server with use_dialogs: true, the inventory closes and the native dialog editor opens (unchanged behavior).
  • Everywhere else, the new AdminConfigInventory opens: a 54-slot inventory with the same 9 categories as the dialog, a Reload button, a Back button, and the same pastel color palette and stained-glass separators used across the config UIs.

Category selector layout

The selector is a 9x6 grid with one category button per row (slots 9-17), the Reload button at slot 22, and the Back button at slot 49. Each category button shows its translated name with a click-to-edit tooltip.

Slot Category Material
9 Language Writable Book
10 Worlds Grass Block
11 Players and friends Player Head
12 Blocks and locking behavior Anvil
13 Entity protection Name Tag
14 Expiry Clock
15 Raid detection Crossbow
16 Notifications Bell
17 Maintenance Damaged Anvil
22 Reload Comparator

Settings per category

Each category inventory lists every setting of its dialog counterpart, in the same order, with the same titles, descriptions, and config keys:

  • Language: replace_translations, fallback_string, plus two sub-screens, "Enable or Disable Languages" (per-language toggles with a global Enable All/Disable All button) and "Select Active Language" (display name, completion percentage, active marker, click to set active).
  • Worlds: per_worlds_config, excluded_worlds (comma-separated world list via chat input).
  • Players and friends: lock_on_place_by_default, public_is_friend_by_default, player_max_locked_block_count, lock_hint_cooldown_in_seconds, friend_search_similarity, disable_friend_functionality.
  • Blocks and locking behavior: modern_family_blocks (flips the blocks.yml storage format on toggle), redstone_disallowed_by_default, simplified_hopper_logic, protect_locked_blocks_from_explosions, block_protected_block_piston_movement, clear_protection_on_shulker_break, allow_break_protected_blocks, respect_spawn_protection, block_lock_effects, block_lock_sounds, use_menus (dialog-only, marked), use_dialogs (dialog-only, marked), timed_access_max_duration_days.
  • Entity protection: entity_protection.enabled, entity_protection.auto_protect_on_tame, villager_workstation_protection.enabled, villager_workstation_protection.radius, villager_workstation_protection.vertical_radius, entity_protection.villager_locate_seconds, entity_protection.menu_item (validated against real material names).
  • Expiry: world_expiry.enabled, world_expiry.check_interval_minutes.
  • Raid detection: raid_detection.enabled.
  • Notifications: notify_op_of_updates, owner_notifications.enabled.
  • Maintenance: auto_reload_configs, auto_reload_delay_seconds (clamped 0-5), inactivity_cleanup_days, enable_session_log, enable_backups.

How editing works

  • Boolean settings are toggle items that apply immediately on click and re-render the screen; the current state is shown in the item name (the inventory equivalent of the dialog's on/off icon), and the item glows when active.
  • Value settings (numbers and text) open the chat input prompt (TextInput) when clicked, the inventory-mode equivalent of the dialog's native text field. The same parse validation runs as in the dialog editor: invalid numbers show the dialogs.admin_config.invalid_number message and the value is not saved; the villager menu item is checked against actual material names before saving.
  • Every change goes through DefaultConfig.setAndSave() or its dedicated setter, which saves to disk, suppresses file-watcher duplicate triggers, and schedules the programmatic reload after the configured auto_reload_delay_seconds.
  • All titles, lore lines, tooltips, hints, and status messages come from TranslationKey; the editor reuses the dialog editor's key set, so both UIs stay in sync from a single translation file.
  • All inventory category screens (AdminConfig*Inventory), UserMenuInventory, and AdminMenuInventory feature a unified, framed layout: dark gray stained-glass pane background borders, centered item slots across rows, and a standardized Back/Close button at slot 49 (bottom center).

Per-World Lockables in the Dialog UI

The last inventory-only lockables screen now has its dialog equivalent. From /bp lockables, a new "Configure per world" button (only shown while per_worlds_config: true, matching the legacy inventory behavior) opens:

  • WorldLockableSelectionDialog: lists every loaded world with its protection status (enabled/disabled), its protected-block count, and a hint when the world has its own config entry. Six worlds per page; clicking a world opens its detail screen.
  • WorldLockableDetailDialog: the per-world material list for that world, sorted by name, nine materials per page. Each row toggles that material inside the world's list in worlds.yml, exactly like the inventory detail screen: worlds without a list of their own start from the global lockable/entity settings, and the first toggle for that world writes a compact family expression (never a flat wall of material names). The toggle runs through the same suppress-then-reload path, logs to the activity log, and confirms in the action bar with the world name in the feedback.
  • Back navigation mirrors the inventory flow: detail goes back to the world selector, which goes back to the lockables dialog.

A note on scope: the dialog detail screen is the same full replication of the lockables list that the inventory detail screen already was; it is not a shortcut that reuses the global lists in place of the per-world ones.

Reload Button in the Dialog Category Selector

The dialog category selector previously had no Reload button while its inventory counterpart did. The AdminConfigDialog categories screen now includes a Reload button at the end of the list, with the same behavior as the Admin Menu dialog's Reload: an immediate reload of config.yml, blocks.yml, and lang/lang.yml via the reload coordinator, reporting success or failure in chat with no review step.

Reload Failure Message Is Now Translated

The reload flow no longer prints a hardcoded English string on failure. A new key, messages.admin_reload_failed ("Reload failed: " / "La recarga falló: "), replaces the literal in both the Admin Menu dialog and the config editor dialog, with the coordinator's error message inserted via the {error} placeholder. This was the last remaining hardcoded player-facing string in the reload path.

Dialog Navigation Refactor

Two new classes replace the largest source of duplicated dialog code:

  • DialogNavigation.backButton(...): one helper builds the Back/Close button from the screen's origin (close label for standalone screens, back label and the correct "return to" tooltip for menu origins). The per-screen originHint/originBack switch blocks were removed from 16 dialog classes: About, AdminMenu, BlockLock, BlockSettings, Debug, EntityBlockSettings, FriendManage, Info, Integrations, Lockables, Protdel, Stats, Unlock, Update, UserMenu, and UserSettings. (AdminConfigDialog keeps its own inline back/close button because the config editor routes back to the Admin Menu dialog instead of using the shared origin helper.)
  • DialogState: a per-player back stack (mirroring the inventory system's origin stack) for the child screens that previously hardcoded "back to BlockLockDialog". Block Settings, Friends, and Entity Settings screens reached from a block lock dialog now push the block lock screen onto the stack and pop it on Back, so returning works even when the same child screen is reachable from several parents. The stack is cleared when a block lock dialog is opened fresh.

AdminConfigDialog Split per Category

AdminConfigDialog went from a single 826-line class holding the selector plus one show method per category to one class per category, each holding exactly its own screens: AdminConfigLanguageDialog, AdminConfigWorldsDialog, AdminConfigPlayersDialog, AdminConfigBlocksDialog, AdminConfigEntityDialog, AdminConfigExpiryDialog, AdminConfigRaidDialog, AdminConfigNotificationsDialog, and AdminConfigMaintenanceDialog. AdminConfigDialog keeps the top-level category selector and the shared button builders. No player-visible behavior changed; the split is purely organizational.

Config Entry Always Opens an Editor

With use_dialogs: false, the Config button in the Admin Menu inventory previously replied with a "config GUI not available" action-bar message. It now opens the inventory editor described above. The messages.admin_config_no_gui translation key and its TranslationKey constant, no longer referenced by any code, were removed in this release.

Menu Order and Dialog Parity

The two top-level menus now show their entries in the same order in both UI modes, and the dialog UIs close the last remaining feature gaps with their inventory counterparts:

  • User menu order: Friends, Settings, Stats, Transfer, About. UserMenuInventory slots were reordered (Friends at 11, Settings at 12, Stats at 13, Transfer at 14, About at 15) to match the order the dialog already displayed.
  • Admin menu order: Lockables, Config, Auto Drop, Remove All Protections, Stats, Integrations, Check for Updates, Reload, Debug, Info, About. AdminMenuInventory slots were reordered (Stats at 19, Integrations at 20, Check for Updates at 21, Reload at 22, Debug at 23, Info at 24, About at 25) to match the dialog order.
  • Transfer in the User Menu dialog: the inventory-only "Transfer all blocks" button now also exists in the dialog version. It opens a native value-input dialog asking for the target player name, then runs the same TransferCommand.transferAll path the inventory button uses.
  • Auto Drop and About in the Admin Menu dialog: both were inventory-only and now appear in the dialog version, Auto Drop after Remove All Protections and About last, mirroring the inventory placement. Auto Drop opens the auto-drop dialog; About opens the About dialog.

All new buttons reuse existing translation keys and dialog components, so no new keys were added to either language file.

Dead Code Cleanup

Verified dead code (each item confirmed to have zero call sites before removal) was removed in this release:

  • BlockInfoInventory.getOnlineProfileOrCreate (zero call sites; the shipped skin path uses SkinCache instead).
  • BlockProtInventory.modifyFriendsForAction(Player, OfflinePlayer, ...): all call sites pass a UUID, so the deprecated OfflinePlayer overload was removed.
  • BlockProtInventory.setPlayerSkull(int, OfflinePlayer) (zero call sites; the PlayerProfile overload and setPlayerSkullAsync cover all screens).
  • BlockProtInventory.toggleEnchants(ItemStack) single-argument overload (zero call sites; the two-argument overload is used internally).
  • The MESSAGES__ADMIN_CONFIG_NO_GUI constant and its messages.admin_config_no_gui key (see above).
  • 67 unused translation keys removed from translations_en.yml and translations_es.yml: the lock-groups feature leftovers (inventories.groups.*, messages.groups.*), legacy flat dialogs.admin_config.* keys superseded by the per-category nested keys, the nested console.boot.* duplicates of the flat boot keys, console.claims_system_enabled/disabled, messages.user_transfer_hint, messages.user_timed_hint, inventories.integrations.none/separator, and worlds.scan_world_added. Both files stay in sync; the completeness check confirms every remaining key maps to a live TranslationKey constant.
  • DefaultConfig.migrateLegacyBlocksIfNeeded() (deprecated empty stub, zero callers).
  • TransferSearchInventory.openSearch(Player) single-argument overload (both call sites use the (Player, Block) overload).
  • The FriendHandler access-flag leftovers getAccessFlagsBitset(), setAccessFlagsBitset(int), getAccessFlags(), and setAccessFlags(EnumSet<BlockAccessFlag>). isManager() keeps its signature but always returns false, which is exactly what the removed feature's empty stubs already produced.
  • The NBTHandler.PERMISSION_LOCK, PERMISSION_INFO, PERMISSION_ADMIN, and PERMISSION_BYPASS constants (zero references; Permissions is the single source of permission nodes).
  • PlayerSettingsHandler.addPlayerToSearchHistory(OfflinePlayer) and addPlayerToSearchHistory(String) overloads (the only call site passes a UUID).
  • UpdateChecker(PluginDescriptionFile) and UpdateChecker(PluginDescriptionFile, List<Player>) constructors (all call sites use the String-based constructors).
  • SemanticVersion.equals(Object) and hashCode() (version objects are never used as map keys or set members; the Object defaults now apply).
  • The spigot module no longer disables -Xlint:deprecation and -Xlint:removal; the module compiles clean with both enabled.

Lockable Blocks Catalog by Family

A new reference file, LOCKABLE_BLOCKS_BY_FAMILY.md, lists the lockable block catalog grouped by family (TILE_ENTITIES, SHULKER_BOXES, BLOCKS, DOORS, ENTITIES) instead of by sub-family. Every material under a family header was verified against the BlockFamilyParser registry that defines family membership; it is an additional view on top of the existing LOCKABLE_BLOCKS_REFERENCE.md, which stays unchanged. Both files carry a cross-reference at the top so a reader lands on whichever ordering they need. No code, config, or translation changes.

Blocks Category Split into Sub-Screens

AdminConfigBlocksDialog was the largest config category (13 settings). It now opens a three-way chooser matching the dialog editor's split:

  • Locking: lock-on-place by default, public-is-friend default, max locked blocks, hint cooldown, friend search similarity, disable friends.
  • Behavior: modern family blocks, redstone disallowed, hopper logic, piston movement, explosion protection, shulker break, allow break protected blocks, spawn protection.
  • Effects: lock effects, lock sounds, use menus, use dialogs, timed access max duration.

AdminConfigBlocksInventory mirrors the same three sub-screens for the inventory editor (its MAIN screen now hosts the three sub-category buttons), keeping the dialog/inventory parity rule intact. Three new TranslationKey entries (DIALOGS__ADMIN_CONFIG__BLOCKS__LOCKING_TITLE, ...__BEHAVIOR_TITLE, ...__EFFECTS_TITLE, "Locking"/"Bloqueo", "Behavior"/"Comportamiento", "Effects"/"Efectos") were added to both language files; the settings themselves reused their existing keys.

Multi-Candidate Player Search

When an add-friend search falls below the configured friend_search_similarity threshold, the plugin no longer returns a dead-end "player not found" if any candidate is close enough:

  • PlayerLookup.findCandidates(query, minSimilarity, limit, exclude) returns up to limit candidates from the same merged online/offline set findBestMatch already scans, paired with their similarity scores (ScoredMatch record), sorted by descending score.
  • The call sites in FriendManageDialog (blocks) and EntityFriendManageDialog (entities) now fall through to the candidate list instead of the error message; the "player not found" message only appears when the candidate list is empty.
  • FriendCandidateSelectionInventory shows up to 26 candidates as player heads (name plus match percentage), back to the friend manage screen on selection or cancel.
  • FriendCandidateSelectionDialog is the dialog equivalent with six candidates per page and prev/next paging, gated by shouldUseDialogs(player) the same way every other dialog screen is.
  • New keys: title inventories.friends.select_candidate ("Select a candidate" / "Selecciona un candidato"), hint dialogs.friends.select_candidate_hint ("Who did you mean? Select a candidate:" / "¿A quién querías decir? Selecciona un candidato:"), and score tooltip dialogs.friends.select_candidate_score ("Similarity: %" / "Similitud: %") in both language files.

Built-in Skin Resolution & Player Head Rendering

SkinCache and player head item rendering received a major overhaul to guarantee player skins render reliably across all inventory screens, including on offline-mode and local development servers:

  1. Instant online player profile resolution: SkinCache checks whether a player is currently online on the server before making any external network requests. If online, player.getPlayerProfile() (which already carries skin textures from Bukkit or SkinsRestorer) is returned instantly in 0 ms without HTTP calls.
  2. Name-only resolution fallback for offline UUIDs: On offline-mode servers (online-mode: false), Bukkit generates version-3 offline UUIDs that Mojang's session servers reject. SkinCache now falls back to name-only resolution (Bukkit.createProfile(name).update()) which queries Mojang's name-to-UUID endpoint first to retrieve the real Mojang UUID before fetching textures.
  3. PlayerDB third tier: When both Bukkit update and SkinsRestorer fail, SkinCache resolves the Mojang UUID via https://playerdb.co/api/player/minecraft/{username} and fetches the signed texture from https://sessionserver.mojang.com/session/minecraft/profile/{uuid}.
  4. Cache failure protection: SkinCache no longer permanently caches textureless profiles, allowing future attempts (when a player logs in or network recovers) to successfully resolve skins.
  5. Universal inventory head support: All 13 inventory GUIs that display player heads (UserMenuInventory, AdminMenuInventory, AdminConfigInventory, UserSettingsInventory, BlockLockInventory, BlockInfoInventory, EntityInfoInventory, FriendManageInventory, EntityFriendManageInventory, FriendSearchResultInventory, FriendDetailInventory, PlayerListInventory, AuditInventory) now use setPlayerSkullAsync. Buttons and heads render with the player's skull and skin while preserving legacy color code formatting on titles and lores and retaining PersistentDataContainer metadata (such as audit_player_uuid in AuditInventory).

Async-Safety Guard

A new AsyncGuard utility fails fast when NBT/tile-entity code runs off the primary thread. On Paper/Spigot, AsyncGuard.assertSync(operation) throws IllegalStateException carrying the operation name when Bukkit.isPrimaryThread() is false; on Folia the check no-ops, since Folia enforces region ownership itself and throws on an actual violation. The guard now protects FriendSupportingHandler.addFriend, its compound() accessor, and every BlockNBTHandler constructor.

As part of wiring the guard in, the only async NBT caller found in the cross-check, InactivityCleanupTask, was reworked: the task now collects candidates on the worker thread (reading only async-safe statistics data) and processes each candidate's NBT on the primary thread via one scheduler tick per batch, so the new guard never trips on a legitimate path. DebugCommand's diagnostics were audited and already schedule their NBT checks on the primary thread, so they needed no changes. Pure internal diagnostics: no new translation keys, no new config keys.

Translation Changes

Eight new keys were added in this release, each in both translations_en.yml and translations_es.yml:

  • messages.admin_reload_failed: reload failure message, used by both dialog reload buttons.
  • dialogs.admin_config.blocks.locking_title, ...behavior_title, ...effects_title ("Locking"/"Bloqueo", "Behavior"/"Comportamiento", "Effects"/"Efectos"): the three sub-screen titles of the split Blocks category.
  • inventories.friends.select_candidate ("Select a candidate" / "Selecciona un candidato"), dialogs.friends.select_candidate_hint, and dialogs.friends.select_candidate_score ("Similarity: %" / "Similitud: %"): the multi-candidate selection screen, in both the inventory and dialog UI.
  • console.update.available_dev ("A new experimental development build (BEDev) of BlockProt Reloaded is available: . It is NOT a stable version and is only published on GitHub." / "Hay una nueva build de desarrollo experimental (BEDev) ..."): the console counterpart of the in-game dev-build message, so a pre-release server is no longer told a dev candidate is a "stable" version (see "Console Update Notification for Dev Builds").

All other screens reuse the existing key set, so the English and Spanish files stay the single source of truth for both interfaces.

Shared Dialog Palette

The six pastel colors used across the dialog system (SOFT_GRAY 0xAAAAAA, PASTEL_MINT 0x8FE3B0, PASTEL_CORAL 0xF0A0A0, PASTEL_GOLD 0xD2B48C, SOFT_BLUE 0xA0C4E8, PASTEL_PURPLE 0xC8A0E0) and the stripColor helper that removes Minecraft color codes from translated strings were duplicated verbatim in 18 dialog classes. They now live in one static-only class, BpDialogStyles, and the 18 classes (About, AdminMenu, Audit, BlockInfo, BlockSettings, Debug, EntityBlockSettings, EntityFriendManage, EntityInfo, FriendManage, Info, Integrations, LockableCategory, Stats, Unlock, Update, UserMenu, UserSettings) import them statically. Dialogs that intentionally use a different accent color (AutoDrop*, BlockLock, Lockables, WorldLockable*, FriendCandidateSelection, Protdel) and the AdminConfig* family, which already centralized its own palette, keep their local definitions. Pure internal change; no player-visible behavior or colors changed.

Console Update Notification for Dev Builds

The in-game update notification already distinguished a BEDev candidate from a stable or hotfix release. The console notification did not: a server running an experimental build that ran /bp update from console, or read the mirrored record in logs/blockprot-*.log, would see "A newer STABLE version ... is available" even when the detected release was a BEDev build. A new console.update.available_dev key ("A new experimental development build (BEDev) of BlockProt Reloaded is available: . It is NOT a stable version and is only published on GitHub." / "Hay una nueva build de desarrollo experimental (BEDev) ...") was added to both language files, and the console path now picks the message by the same release-channel split as the in-game path (stable, hotfix, or dev). The boot checklist line is unaffected; it already used its own channel-agnostic wording.

Debug Coverage of the Version-Suffix Table

/blockprot debug group 25 (Utility helpers) now exercises SemanticVersion against the suffix-ranking table documented in gradle.properties: it confirms blank is a stable release, BEDev/bdev/SNAPSHOT-3 are pre-releases, hotfix and fix.1 are hotfixes ranked above the clean release, legacy -RELEASE is normalized to a clean release, and exp is experimental. It also verifies compare order between ranks, the numeric counter tiebreak (1.3.4-BEDev.2 > 1.3.4-BEDev.1), numeric-segment comparison, and baseVersion() stripping. This closes the one remaining untested utility the version-detection system relied on. No new translation keys were needed (debug output goes through BlockProtLogger).

Admin Menu Update Button Notifies Operators Only

The "Check for updates" button in the Admin Menu inventory previously sent the update notification to every online player, not only operators. As of this release it filters its recipients to ops, matching the join notification which is already op- and config-gated (notify_op_of_updates). Players keep only the user-facing BPR options; admins configure and receive everything. No new translation keys; the button, its translated label, and its tooltip are unchanged.

Debug Diagnostics Coverage

/blockprot debug no longer leaves whole subsystems untested. The diagnostics suite grew from 20 to 28 groups:

  • Group 21, All dialogs: builds every dialog screen through a no-op bridge (DialogBridgeFactory.setTestBridge) so the full dialog UI is smoke-tested without opening real dialogs on the player. 39 of 40 screen classes are exercised with the same debug-chest and temporary-ArmorStand fixtures the inventory group uses; only AdminConfigValueDialog (a field-input helper without a show entry point) is skipped. The real bridge is restored afterwards.
  • Group 17, All inventories: grew from 18 to 40 inventory classes. All 10 AdminConfig*Inventory editors, the auto-drop, lockables, per-world, unlock, candidate-selection, entity, transfer-search, and world-delete screens were added. PlayerListInventory is skipped with a logged reason: its only entry point opens a live GUI, unlike every other screen's fill().
  • Group 22, Commands registered: confirms the blockprot command resolves with an executor, and that every Permissions enum constant is declared in the plugin.yml permissions section (read from the jar resource). It also verifies all 18 *Command classes load and that all 8 integration classes are actually constructed in onLoad() by comparing against the live integration list, so a class that exists on disk but was never wired up now shows up as a failed check.
  • Group 23, Listeners registered: compares the listeners actually registered through HandlerList against the 17 active listener classes, so a listener that exists on disk but was never wired up in onEnable() now shows up as a failed check.
  • Group 24, SkinCache tiers: exercises the online/cached profile path for the debug player and confirms the SkinsRestorer tier no-ops cleanly when SkinsRestorer is not installed.
  • Group 25, Utility helpers: exercises the pure static logic: DurationParser parse/format, DurationLimits validation, StringUtil distance/similarity, BlockUtil block names, AsyncGuard main-thread assertion, PlayerNameResolver, TemporaryActionBar, BpDialogStyles palette and stripColor, DialogNavigation back buttons, DialogState push/pop, ReloadReport snapshot diffing, IntegrationConfig, and AdminConfigValueDialog through the no-op bridge.
  • Group 26, NBT sub-handlers: exercises FriendSupportingHandler/FriendHandler friend add/remove/query on a chest fixture, RedstoneSettingsHandler protection toggles, BlockCountStatistic, EffectGeometry bounding boxes, ProtectedBlockCache mark/unmark, EntityProtectionHandler on a temporary ArmorStand (structural-only when the entity type is unsupported), LocationListEntry, and PlayerInventoryClipboard set/contains/remove.
  • Group 27, Structural classes: load-checks the classes that cannot be instantiated from a diagnostics run (event classes, chat-input gateways, tasks, console, metrics formatter, config base, storage, abstract statistic bases) so their presence in the jar is proven instead of silently skipped.
  • Group 28, Class coverage: enumerates every screen class actually present in the plugin jar under the four screen packages (inventories, dialogs, commands, listeners) and reports a failure for any concrete class the run did not touch, so a screen added in a future version shows up as a red line instead of silently shipping untested. Classes are matched by the screen naming convention (*Inventory, *Dialog, *Command, *Listener); abstract classes, interfaces, enums, inner classes, and non-screen helpers are skipped. In a dev workspace (not running from a jar) the group logs that it is skipped instead of failing. Current tree: 45 inventories, 41 dialogs, 18 commands, 19 listeners.

Together with the earlier groups, every one of the 214 classes under de/sean/blockprot/bukkit is now either exercised directly or load-checked. All new checks report through the existing debug logger and translation keys; no new keys were needed.

Build and Compatibility

  • gradle.properties set to 1.3.5 with a blank versionSuffix, shipping as a clean stable release.
  • No dependency or toolchain changes; the plugin still targets Java 21 bytecode with api-version 1.21.1, keeping the dialog system gated behind the Paper 1.21.7 runtime check.
  • The dialog and inventory editors behave identically regardless of use_menus; use_dialogs only decides which of the two opens.
  • The per-world lockables dialog entry appears only while per_worlds_config: true, matching the legacy inventory button.

Additional Fixes and Polish

Additional fixes and polish included in this release:

  • ESC returns to the parent menu in inventories: pressing ESC (or E, or closing a submenu window) on an inventory that was opened from another BlockProt menu now reopens the parent menu one tick later, using the same origin stack the back button uses. Programmatic navigation (a menu that opens another menu in code) is unaffected because the new window is already open when the check runs. Top-level menus still close normally on ESC.
  • Auto Drop is now reachable only from Lockables: the Auto Drop entry was removed from the Admin Menu (both the inventory and the dialog version). The screen is still available under /bp lockables > Auto Drop, matching the intended flow, and its back button returns to Lockables from every level of the auto-drop screen (family list and per-family page).
  • Auto Drop now applies to operators and admins: regular auto-drop blocks previously skipped the breaker when they held operator or admin privileges, while shulker boxes always used the inventory path; now every block listed in auto_drop_to_inventory.blocks delivers its drops to the breaking player's inventory for all players alike (still excluding creative mode). The admin guide was updated to match.
  • Blocked breaks no longer leak auto-drop items: when a player without access broke a protected block that was listed in auto_drop_to_inventory.blocks, the block's item was placed in their inventory one priority step before the protection handler cancelled the break, duplicating the item while the block remained intact. The auto-drop handler now mirrors the protection decision and skips breaks that are about to be blocked, so nothing is delivered. The check covers every lockable block: the original fix only guarded tile-entity holders, so doors, trapdoors, fence gates, beds, anvils and cauldrons still leaked their item until the guard was moved above the tile-entity branch.
  • Auto drop now covers entities: the same auto-drop-on-break behaviour applies to the lockable entity families (item frames, glow item frames, storage minecarts, hopper minecarts, chest boats). Their contents drop straight into the breaking player's inventory, the same protection mirror applies (a protected vehicle breaks only for its owner or an admin; a linked frame follows its block's protection), and creative mode is still excluded. Nothing is delivered when the break is about to be blocked, so no duplication. The admin guide now documents this.
  • Auto-drop block search: the Auto-Drop screen (inventory and dialog) gained a creative-style block search: a compass entry in the inventory and a search button in the dialog open a chat prompt, and matching materials are listed in relevance order (exact match, starts-with, word prefix, contains, Levenshtein within 2 edits) with the same one-click toggles as the family pages. A query with no matches shows a notice.
  • Debug check counters updated: the diagnostics suite now exercises AutoDropSearchInventory (group 17), AutoDropSearchDialog (group 21), and AutoDropEntityListener (group 23); group 28's tree count is now 45 inventories, 41 dialogs, 18 commands and 19 listeners.
  • Back buttons return to the menu they came from: About opened from the Admin Menu dialog returns to the Admin Menu dialog (it previously closed), BlockLock opened from the User Menu returns to the User Menu dialog, and the auto-drop back chain follows the actual entry point instead of hardcoding Lockables.
  • Lockables categories match the inventory: the dialog category list now uses the exact same classification as LockablesInventory: a Beds category was added between Trapdoors and Gates (beds were previously lumped into Interactive), Storage gained the missing tile entities (shelves, crafter, brewing stand, hopper, dispenser, dropper, beehive, bee nest, jukebox, lectern), workstations match the seven tables plus anvil, hanging wall signs are recognized, Entities lists the whole entity family, and remaining block-family members fall back to Interactive. Category order is identical to the inventory enum.
  • Access Log hides the owner: the block and entity access log (both the inventory and the dialog view) filters out the owner's own entries, showing only accesses by non-owner players. Actions logged by the owner's own container interactions no longer clutter the history.
  • Pale oak signs are lockable: PALE_OAK_SIGN and its wall, hanging, and wall-hanging variants were rejected by the tile-entity validator in DefaultConfig because signs were missing from the tile whitelist; the validator now accepts every _SIGN variant, so entries in blocks.yml resolve to a lockable material. The blocks.yml integrity check no longer reports them as mismatched.
  • Separate debug report file: /blockprot debug now writes to logs/debug-report-<timestamp>.log next to the session log, and while a run is active the session log receives nothing (no more diagnostic noise mixed into the activity log). The report opens with a header that includes the plugin version, the player, server, API and Java versions, and compatibility strings; it ends with an explicit end marker. Both file paths are announced in chat when the run finishes.
  • Debug checks closed: group 17 skips EntityInspectContentsInventory with a logged reason (it requires a live container entity, not reproducible with an ArmorStand), group 19 accepts the pale oak sign family, and group 28 now covers BlockProtCommand, which group 22 touches when it verifies the registered executor. The diagnostics run reports 0 failures on a stock server.
  • Auto-drop now delivers the real drops for every listed block: the non-shulker path used setDropItems(false), which the server ignores for tile-entity contents, so chests, trapped chests, furnaces, blast furnaces, smokers, dispensers, droppers, hoppers, barrels, brewing stands, chiseled bookshelves, decorated pots, and crafters delivered only the empty block item to the inventory while their actual contents spilled on the ground; doors and beds (double blocks) were equally fragile because the cancel path did not remove the partner half. The handler now mirrors the shulker path: it cancels the break, captures both getDrops(tool) and the tile-entity snapshot inventory via Container.getSnapshotInventory(), sets the clicked block (and the verified complementary half for doors and beds) to AIR, and delivers the block item plus the contents to the breaker's inventory in one step. Only the clicked half of a double chest is delivered (its single 27-slot snapshot, not the combined 54-slot view), so no items are duplicated or lost; doors and beds still drop exactly one item, matching vanilla, while both halves are removed. The stat/hopper cleanup the protection handler normally runs on a successful break is now replicated on the cancelled path, so owner counters and hopper caches stay consistent. The item-frame auto-drop now resolves projectile breakers too, so a frame or glow frame knocked off by an arrow or trident routes its contents and itself to the shooter the same way a direct punch already did.
  • Vehicle destruction exception fix: AutoDropEntityListener.onVehicleDestroy now filters out null items (empty slots) when collecting the contents of destroyed chest boats and storage minecarts, preventing an IllegalArgumentException from Bukkit's addItem().
  • Bed bottom auto-drop fix: BlockEventListener.onAutoDropBlockBreak now retrieves drops from the opposite half of double blocks (such as beds) when the clicked half returns empty drops, ensuring the item is always delivered regardless of which part is broken.
  • Auto-drop configuration debug check: /blockprot debug group 4b (AutoDrop) was added to verify the auto-drop setting and the configured auto-drop materials list, ensuring the configuration matches expectations in diagnostic reports.
  • AuditDialog crash on entities fix: Trying to open the Audit Log from a block lock dialog applied to an entity (like a Boat or Minecart) will no longer crash the server with a "not a lockable block" RuntimeException if the entity is standing on a non-lockable block like snow.
  • Dialog toggle visual glitch fix: Added a 1-tick delay when reopening Paper/Floodgate native dialogs after a button click (such as toggling boolean config values), preventing race conditions where the Bedrock or Java client would occasionally ignore the new dialog state. (Reported by TankObliterator)
  • Block name input menu flow: Fixed a timing issue where clicking "Set block name" in block lock menus immediately reopened the menu on inventory close, allowing players to type their desired name in chat uninterrupted.
  • Author and maintainer credits separation: Updated the about command output and dialog labels so author and maintainer credits are rendered on distinct lines with dedicated translation keys.
  • Statistics phantom block and air filtering: Statistics and block listings now filter out coordinates where the block in the world has been destroyed or turned into non-lockable materials like air or snow, preventing phantom block entries or incorrect chest icons.
  • First start guide pastel styling: updated the in-game first start guide broadcast on operator join (first_run) from legacy harsh gold and yellow to the plugin's standard pastel hex color scheme (#D2B48C pastel gold, #8FE3B0 pastel mint, and soft gray) in both English and Spanish translations.
  • Context-aware Back vs Close in menus: inventories opened directly via commands (such as /bp protdel, /bp lockables, /bp unlock, /bp stats, /bp expiry, and auto-drop screens) now detect when they have no parent menu origin and correctly display the Barrier "Close" button instead of "Back", cleanly closing the inventory on click.
  • Expanded bundled language templates (25 languages total): added translation templates for Arabic (translations_ar.yml), Hebrew (translations_he.yml), Romanian (translations_ro.yml), Swedish (translations_sv.yml), and Ukrainian (translations_uk.yml) in spigot/src/main/resources/lang/ and registered them in Translator.DEFAULT_TRANSLATION_FILES. AdminConfigLanguageInventory and AdminConfigLanguageDialog were expanded to display and paginate all 25 languages. Full key parity (774 keys) is maintained across English and Spanish reference files.
  • BlockUtil regex caching: cached the underscore pattern in BlockUtil as a pre-compiled Pattern instead of recompiling per call, reducing allocation overhead during block and item name formatting.

Future Changelog Format (1.3.6+)

Starting with release 1.3.6, BlockProt Reloaded release notes and changelogs will adopt the Keep a Changelog 1.1.0 format (with standard Added, Changed, Deprecated, Removed, Fixed, and Security sections) to ensure structured, consistent, and easily diffable change records across releases.

Commits

  • 5cce389: Update 1.3.5.RELEASE_NOTES.md.
  • 0ea5599: Add missing commits to 1.3.5 commits section.
  • a3280f5: Add title image to LOCKABLE_BLOCKS_BY_FAMILY.md.
  • dfccd89: Create LOCKABLE BLOCKS BY FAMILY.png.
  • c000402: Cache underscore regex in BlockUtil; add 1.3.5 commits section.
  • 7ac7ebe: Improve menu origin awareness, add first-run pastel styling, and expand language templates.
  • de48b19: Use updated isLockable API.
  • 9272fe6: Fix release notes image paths.
  • 8457784: Fix auto-drop: block contents, door/bed halves, and frame projectile breaks.
  • 4ed0c1a: Renamed release images folder.
  • cf95251: Update MODR_HANG_README.md.

This mod has no additional files