
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.
Список изменений
!1.3.4
Summary
This release adds a Paper dialog-based menu system as an alternative to the legacy inventory GUIs. The recommended peak experience is use_menus: true combined with use_dialogs: true on Paper 1.21.7+: consolidated /bp user and /bp admin menus rendered as native Minecraft dialog windows, with an in-game AdminConfigDialog to edit config.yml without touching files.
When use_dialogs: false (default), behavior is unchanged from previous versions: legacy inventories work on any server software.
An in-game admin config editor (AdminConfigDialog) mirrors config.yml section by section, letting admins modify settings directly. The lockables menu was reworked with a sub-dialog for individual material toggling.
A new language management system adds language enable/disable via lang/lang.yml, an in-game language selector cycling through the 15 registered languages with completion percentages, and automatic translation completion tracking.
Config.yml had minor cleanup (removed a deprecated leftover config block, added the use_dialogs key), and the plugin log file now recovers automatically if it's deleted or truncated while the server is running.
Note: The Residence/GriefPrevention/ClaimChunk integrations, the centralized
integrations.yml, the PaperPlayerProfileskin-resolution migration, and the per-block protection expiry removal were not part of the 1.3.4 commit range: they were already present as of 1.3.3 and are documented in the 1.3.3 release notes. They have been removed from this document to avoid re-claiming pre-existing work as new.
Community Feedback Fixes
A tester gave feedback on the dialog system shortly after it landed. Three items came out of that:
/bp usernow takes priority over/bp adminwhen/blockprotis run with no arguments, matching the convention used by other plugins. Admins still reach the admin menu explicitly via/bp admin.- The Statistics tab in
/bp useris now Placements. It shows your locked block count against the server limit (Your Protected Blocks: 12/24, or just the count if the server has no limit set), lists your blocks grouped by material with world and coordinates, and dropped the global server-statistics toggle entirely, since that never belonged on a personal stats screen. Clicking a block opens it directly for editing instead of only offering a teleport. The admin-side Statistics screen (Admin Menu > Stats) is unchanged and still has both the player and global-server pages. - Admin config editor buttons now show a short, readable name instead of the raw
config.ymlkey (for examplelock_hint_cooldown_in_secondsnow reads "Lock Hint Cooldown"). The longer description and the raw key are still shown in the tooltip for anyone who wants the technical detail.
The sign-closing-instantly bug reported in the same feedback was already fixed earlier in this cycle by the native dialog text input described below.
Follow-up bug found during that same testing pass
- (bug) Opening any container could throw
RuntimeException: Given block X is not a lockable block/tile entityand spam the console, most visible withper_worlds_config: trueon a world whose per-world lists are still empty (the default right after/bp lockablesauto-scans a new world). Several listeners (InventoryEventListener,BlockEventListener,PistonEventListener,RedstoneEventListener) checked whether a block was lockable using the config-wide check, which ignoresper_worlds_config, whileBlockNBTHandleralways validates per-world. When the two disagreed, the handler threw. All of those checks now use the per-world-aware check so they agree withBlockNBTHandler. - The Placements block list showed a "click to teleport" hint even though clicking actually opened the block's edit dialog whenever the block was still lockable (teleport only happens as a fallback once a block drops out of the lockable list). The hint now matches whichever action a click will actually perform.
Lockables toggle and auto-reload timing fixes
- (bug) Disabling specific materials inside a mostly-active lockable category could silently re-enable them.
BlockFamilyParser.toFamilyExpression()could write a malformed expression like[* CHEST COPPER_CHEST ...]: a global*(meaning "everything") followed by plain material names that do nothing to exclude anything from that*. The next time that expression was parsed, every material in the family came back active. Fixed so the compact writer never mixes a global*with bare inclusion names; it always falls back to the explicit exclusion form (*-TAG -missing...) in that case. - (bug) Auto-reload after a lockables change sometimes fired much later than
auto_reload_delay_seconds, or an extra reload showed up out of nowhere. The file watcher ignored its own writes for a fixed 3-second window regardless of the configured delay. With a higher delay, several rapid toggles, or slow OS-level file-watch delivery, that window could expire before the write's own change event arrived, so the watcher mistook its own write for an external one and queued a second reload on top of the first. The self-write suppression window is nowmax(3s, auto_reload_delay_seconds + 2s)instead of a fixed 3s. - (bug) The hover tooltip on an individual material button in the lockables dialog read "Click to enable all." / "Click to disable all.", even though the button only toggled that one material. Individual material buttons now use new
dialogs.click_enable_single/dialogs.click_disable_singletranslation keys ("Click to enable." / "Click to disable."); the existingdialogs.click_enable/dialogs.click_disable("...all.") keys are unchanged and still used by the category-level and enable-all/disable-all buttons, where "all" is accurate. - The lockables category indicator (dialog) and the "select all" indicator (inventory) now share a third, orange state for a partially-active category, instead of only showing green/red (dialog) or green/red/gold (inventory). Gold was replaced by the same orange used in the dialog for consistency. Orange is now reserved for counts sitting near the midpoint (a 40-60% band, widened to 30-70% for categories of 5 or fewer materials); other partial states show the normal mint/green color instead of orange for every partial count.
/bp recommendedis split into two independent console subcommands./bp recommended blockswrites onlyblocks.yml(lockable lists, auto-drop), while/bp recommended configwrites onlyconfig.yml(enablesmodern_family_blocks,use_menus, anduse_dialogs, the recommended settings that are not on by default)./bp recommended allapplies both halves in sequence. Each half applies only once: arecommended_blocks_appliedflag is stored insideblocks.ymland arecommended_config_appliedflag inconfig.yml; re-running an already-applied half is a no-op that logsrecommended_already_appliedinstead of silently overwriting the file again (which previously discarded any manual edits made since). Passingforceas the third argument (/bp recommended blocks force//bp recommended config force//bp recommended all force) bypasses the guard and re-applies that half.- Auto Drop to Inventory is now reachable from the Dialog UI, not just the legacy inventory.
LockablesDialoggained an Auto Drop button leading toAutoDropDialog(per-family status list) andAutoDropFamilyDialog(per-material toggles within a family, 9 per page), mirroringAutoDropInventory/AutoDropFamilyInventory. Per-world lockables selection in the Dialog UI was intentionally left out of this pass (seedocs/ZYZ/FOR_LATER.md, planned for 1.3.5) since it requires porting a full per-world config screen, not a simple list.
Paper Dialog System (use_dialogs: true)
The dialog system is the suggested interface for Paper 1.21.7+ servers. It uses Minecraft's native dialog API for cleaner, more intuitive menus. The old inventory system continues to work for servers running Spigot, older Paper versions, or anyone who prefers the original layout.
When use_dialogs: true is set, the plugin checks for the Paper dialog API at runtime. If unavailable, it falls back to normal inventories and logs a warning.
All dialogs use a pastel color palette, support pagination where needed, track navigation history via DialogOrigin, and read translations from translations_en.yml and translations_es.yml.
The DialogOrigin enum tracks which menu opened each dialog. Back buttons return to the correct origin: NONE (individual command mode, back closes the dialog), USER_MENU (returns to UserMenuDialog), ADMIN_MENU (returns to AdminMenuDialog), and INFO (read-only block info mode).
Corrected during development: the standalone commands
/bp lockables,/bp stats,/bp info, and/bp protdelwere passingADMIN_MENUorUSER_MENUas their dialog origin even when invoked directly, not from within the admin or user menu. This made their Back button navigate into a menu the player never opened. They now passNONEwhen invoked as standalone commands, so Back correctly closes the dialog instead of jumping into an unrelated menu. Origin is still passed correctly asADMIN_MENUwhen the same dialogs are opened from withinAdminMenuDialog.
Interaction with use_menus
use_menus controls consolidated (/bp user, /bp admin) vs individual subcommand routing when use_dialogs: false. When use_dialogs: true, all interfaces use dialogs regardless of use_menus. When use_dialogs: false, behavior is unchanged from previous versions.
New Dialog Screens
| Dialog | Access | Purpose |
|---|---|---|
UserMenuDialog | /bp user | Consolidated user menu (settings, friends, stats, about) |
AdminMenuDialog | /bp admin | Consolidated admin menu (lockables, config, reload, update, integrations, stats, debug, info, expiry) |
UserSettingsDialog | /bp settings | Toggle auto-lock, hints, notifications |
FriendManageDialog | /bp friends | Add/remove friends, public/private toggle. Toggling public/private updates all existing owned blocks. |
StatsDialog | /bp stats | Player and server-wide block statistics (2 pages) |
InfoDialog | /bp info | Paginated player block list (7 per page), click a player to view their block info |
LockablesDialog | /bp lockables | 11 material categories (6 per page), click to open sub-dialog |
LockableCategoryDialog | (sub-dialog) | Individual material toggles within a category (9 per page) |
AutoDropDialog | Lockables Dialog > Auto Drop | Per-family auto-drop-to-inventory status list |
AutoDropFamilyDialog | (sub-dialog) | Individual material auto-drop toggles within a family (9 per page) |
UnlockDialog | /bp unlock <player> | Paginated block list for admin unlock (6 per page), includes cache invalidation after unlock. No-argument opens player list. |
ProtdelDialog | /bp protdel | World selector, batched deletion (20 blocks/tick), undo with timestamps and per-player history |
AboutDialog | /bp about | Plugin version, maintainer, issue tracker |
UpdateDialog | /bp update | Cached version check with Check Now button. Results refresh the dialog instead of sending to chat. |
IntegrationsDialog | /bp integrations | List of plugin integrations with enabled status |
AdminConfigDialog | Admin Menu > Config | In-game config.yml editor (see below) |
Recommended Configuration: The 1.3.4 Peak Experience
For the best user experience, enable both use_menus and use_dialogs in config.yml:
# config.yml
use_menus: true
use_dialogs: true
This unlocks the full 1.3.4 experience:
/bp useropens the consolidatedUserMenuDialog: settings, friends, stats, and about all in one place./bp adminopens the consolidatedAdminMenuDialog: lockables, config editor, reload, update checker, integrations, stats, debug, info, and world protection management.- Individual subcommands (
/bp settings,/bp friends,/bp lockables, etc.) are hidden from tab-complete but still accessible if typed directly. - The
AdminConfigDialogmirrors every section ofconfig.ymlfor in-game editing: no more file edits on the server. - Everything uses Minecraft's native dialog windows: cleaner menus, no chest inventories, no anvil prompts, no chat-based input.
When use_dialogs: true, the plugin checks for Paper's dialog API at runtime. If unavailable (Spigot or Paper < 1.21.7):
- A warning is logged with the translation key
CONSOLE__DIALOGS_UNAVAILABLE use_dialogsis automatically set tofalseinconfig.ymland saved to disk- The plugin falls back to legacy inventories: no crash, no data loss
- On the next reload or restart, the check runs again (so if the server is later upgraded to Paper 1.21.7+, the admin can re-enable dialogs manually)
If your server runs Paper 1.21.7+, this configuration is strongly recommended. Servers on Spigot or older Paper versions should leave
use_dialogs: false(the auto-disable handles it) and may optionally useuse_menus: truefor the consolidated inventory GUI.
AdminConfigDialog
A master config editor accessible from Admin Menu > Config. It mirrors config.yml section by section in the same order.
Categories and settings:
- Language:
replace_translations,fallback_string, plus two sub-menus: "Enable or Disable Languages" (toggle individual languages inlang.yml) and "Select Active Language" (choose the activelanguage_file) - Worlds:
per_worlds_config - 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,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],use_dialogs [Dialog],timed_access_max_duration_days - Entity protection:
entity_protection.enabled,entity_protection.auto_protect_on_tame,villager_workstation_protection.enabled - 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(0-5 s, 0 = next tick),enable_session_log,enable_backups
Boolean settings toggle on click. Settings that only apply in dialog mode (use_menus, use_dialogs) are tagged [Dialog] with a tooltip marker and use _de suffix in translation keys (e.g., BLOCKS__USE_DIALOGS_DE).
AdminConfigValueDialog - Native Text Input
Five numeric settings (player_max_locked_block_count, lock_hint_cooldown_in_seconds, friend_search_similarity, timed_access_max_duration_days, world_expiry.check_interval_minutes) no longer close the dialog and open a SignInput or AnvilInput inventory. They use Paper's native TextDialogInput field inside the dialog itself. The value is submitted with the same click that confirms it - no dialog close or reopen. Parse errors show an in-dialog error message instead of closing the screen.
When the dialog API is unavailable (Spigot or Paper < 1.21.7), the editor falls back to SignInput or AnvilInput automatically.
Set Block Name Uses Dialog Text Input
Block name editing (INVENTORIES__SET_BLOCK_NAME) from the block lock dialog now also uses the native dialog text input via AdminConfigValueDialog.openText(), instead of closing the dialog and opening an AnvilInput inventory. The block name is entered in-place inside the same dialog, with a "Confirm" button to save it.
Dialog Text Input Save Button
Every DialogTextField now has a separate confirm button label (confirmLabel), decoupled from the input field label. The AdminConfigValueDialog passes "Confirm" (DIALOGS__ADMIN_CONFIG__CONFIRM_VALUE) as the button text, so the save action is clearly labeled instead of reusing the config key name as the button text.
LockableCategoryDialog
The LockablesDialog previously toggled every material in a category at once, causing inconsistent results (some activating while others deactivated). Now each category opens LockableCategoryDialog, a sub-dialog showing individual materials (9 per page). Each material has its own on/off toggle. No more bulk toggling. Each material row now also shows its real item icon next to the toggle.
The "Enable All" button at the top of each category uses compact family-expression notation (e.g. [*-SIGN]) to activate every member of that sub-family in a single line. Individual toggles write specific material names within the same expression format. Both forms are valid family expressions and compress automatically when the full sub-family is active.
Bed Lockability
Beds can now be added to lockable_blocks (including via the [*-BED] family expression used elsewhere in this document). A bed occupies two blocks (head and foot); locking, unlocking, or breaking either half now applies to both halves as a single unit, the same way double chests are already handled. Breaking one half while the other is in an unloaded chunk is safely skipped rather than throwing.
Dialog Cursor Behavior Fix
Every dialog now sets afterAction: none, so clicking a button no longer forces Minecraft to close and regenerate the dialog screen behind the scenes. Buttons that navigate to another dialog, or that only need to close the current one, now close the dialog explicitly instead of relying on the client's default post-click behavior. This avoids the client recentering the mouse cursor on every click, which previously happened because each click was treated as a brand new screen being opened.
On a Paper 1.21.8+ server, closing a dialog uses the dedicated dialog-close API. On a server running exactly Paper 1.21.7, that API method is not yet present, so the plugin falls back to closing the player's open screen through the older, general-purpose method instead. Both paths produce the same result for the player; the fallback only matters on that one specific Paper version.
Commands Updated for Dialog Mode
| Command | Behavior with dialogs enabled |
|---|---|
/bp stats | Opens StatsDialog |
/bp info | Opens InfoDialog (player list). Click a player to view block info in read-only mode. |
/bp lockables | Opens LockablesDialog |
/bp unlock | Opens UnlockDialog with player list when no argument given |
/bp unlock <player> | Opens UnlockDialog for the specified player |
/bp about | Opens AboutDialog |
/bp update | Opens UpdateDialog. Check Now refreshes the dialog with results. |
/bp integrations | Opens IntegrationsDialog |
/bp settings | Opens UserSettingsDialog |
/bp friends | Opens FriendManageDialog |
/bp user | Opens UserMenuDialog |
/bp admin | Opens AdminMenuDialog |
DefaultConfig API Additions
20+ public setter methods for runtime config modification, added to DefaultConfig:
getBukkitConfig(): direct access to the underlyingFileConfigurationsetAndSave(key, value): set any config value and save to disk- Individual setters:
setLockOnPlaceByDefault,setPublicIsFriendByDefault,setSimplifiedHopperLogic,setProtectFromExplosions,setBlockPistonMovement,setClearProtectionOnShulkerBreak,setAllowBreakProtectedBlocks,setRespectSpawnProtection,setLockEffects,setLockSounds,setWorldExpiryEnabled,setEntityProtectionEnabled,setNotifyOpOfUpdates,setSessionLogEnabled,setBackupsEnabled,setAutoReloadConfigs,setAutoReloadDelaySeconds(clamped 0-5),setRedstoneDisallowedByDefault,setLanguageFile,setPlayerMaxLockedBlockCount,setLockHintCooldown,setFriendSearchSimilarity
Configuration Reload Transactions (auto_reload_delay_seconds)
Previously, the plugin reloaded configuration files as soon as the file-watcher detected any write. This caused double-reloads when external editors wrote files in multiple chunks and made it impossible to coordinate multiple related changes into a single reload.
Starting in 1.3.4, a quiet-period transaction system wraps every reload trigger:
auto_reload_delay_seconds(default2, range0-5) sets the quiet period.0means reload on the next server tick (effectively immediate but never mid-write);2batches an editor's double-write or several files edited back to back into a single reload without feeling laggy.- On each file-change event a generation counter is incremented and a scheduled task is posted. When the task fires it compares the current generation to its own; if another write happened in between, the old task self-cancels and only the latest fires.
- Writes from the plugin itself (config saves from the dialog editor) inject a write token keyed by the exact file path. The watcher consumes and discards any event whose path matches a held token, preventing self-triggered reloads.
- In manual mode (
auto_reload_configs: false), external YAML edits and dialog changes are still written to disk immediately, but the automatic reload does not fire. The change takes effect on the next/bp reload, the next click of the Reload button in the Admin Menu, or the next server restart.
Corrected during development: the language-file completion-percentage writer (
updateLangCompletionPercentages()) rewrotelang/lang.ymlon every reload without checking whether anything had actually changed, and without registering a write token first. Combined with a path-matching bug in the file watcher for files underlang/, this created a self-sustaining reload loop: each automatic reload rewrotelang.yml, which the watcher saw as an external change, which triggered another reload. The writer now skips the write entirely when content is unchanged, and registers its write token before saving when it does write. The watcher's path matching for thelang/subdirectory was also fixed to consistently include thelang/prefix. Config toggles made throughAdminConfigDialog(DefaultConfig.setAndSave()) now also register a write token before saving, so an in-game toggle no longer triggers a redundant automatic-reload cycle for a change the plugin itself already applied.
The new key is editable from the Maintenance section of AdminConfigDialog using the native text-input field (accepts 0-5).
Configuration Reload Behavior
Clicking Reload in the Admin Menu (gold/PASTEL_GOLD colored) runs an immediate reload of config.yml, blocks.yml, and lang/lang.yml and reports success or failure directly in chat. The reload runs as soon as the button is clicked, with no separate review or confirmation step.
ReloadReport compares individual leaf config values, not whole config sections, when building a diff for the session log. YamlConfiguration.getValues(true) returns both a config section as a whole object and its individual child keys in the same map, and the whole-section object has no value-based equality, so comparing only leaf values keeps logs/blockprot-*.log reporting only keys that actually changed on a given reload.
Activity Logging (BlockProtLogger - Mandatory)
BlockProtLogger previously logged only when enable_session_log: true. As of 1.3.4 the logger is always active. enable_session_log now controls only whether the session header is written at startup; the file is always opened and written.
New in this release:
- Java Logger mirror: a
java.util.logging.Handleris attached to theBlockProtlogger ononEnable. EveryLogger.info/warning/severecall is automatically echoed into the log file with its level prefix. No manualBlockProtLogger.log()calls are needed for console output. - Reload reports:
ReloadCoordinatorsnapshots all config values before and after every reload and appends a structured diff:[RELOAD] Triggered by: DIALOG_CONFIRM | Player: Steve [RELOAD] auto_reload_delay_seconds: 3 -> 0 [RELOAD] block_lock_effects: true -> false [RELOAD] 2 key(s) changed. - Re-entrancy guard: the mirror handler sets a boolean flag before logging to prevent infinite loops if the logger itself emits a warning.
Adaptive Particle Geometry (EffectGeometry)
Previous versions placed block_lock_effects particles at four fixed corners of a 1x1x1 cube regardless of the actual block shape.
EffectGeometry (new in 1.3.4) computes the real bounding box for any block and samples particle positions uniformly around its perimeter:
| Block type | Geometry used |
|---|---|
| Single block | Block.getBoundingBox(): exact block-model bounds |
| Bed | Union of head + foot block bounding boxes: one continuous rectangle |
| Double chest | Union of left + right chest bounding boxes: one wide rectangle |
Particles are placed at evenly-spaced points along the perimeter edges of the union bounding box, so beds and double chests show a proportionally wider ring. The sound effect plays once at the geometric center of the union.
LockEffectListener was updated to call EffectGeometry.perimeterPoints() and EffectGeometry.center().
Language Config (lang/lang.yml)
New config file lang/lang.yml under the lang/ directory controls:
- Fallback language: when a translation key is missing from the active language file, the plugin looks for it in the configured fallback before falling back to the raw key name. Default:
translations_en.yml. - Language enable/disable: each of the 15 registered languages has a true/false flag. Disabled languages are not parsed at startup, reducing YAML warnings. The active language from
config.yml'slanguage_fileis always loaded regardless of its enabled flag. - Completion percentages: on every reload, the plugin computes each language file's translation completion percentage and writes it as an inline comment in
lang/lang.yml.
GitLocalize Integration
Translations are now managed through GitLocalize. The project page tracks completion percentages per language and accepts community contributions through a split-view editor. The .gitlocalize.yml config points at translations_en.yml as source and all 20 translation files (19 targets plus the en source, including the staged hu/nl/th/fi/id templates) as synchronize sources.
The badge showing overall translation progress is displayed in the README:
In-Game Language Selector
The admin config dialog's Language section (/bp admin > Config > Language) is now split into two sub-menus:
- Enable or Disable Languages: Toggle which languages are loaded on startup via
lang/lang.yml. Each language has its own enable/disable toggle, plus a global "Enable All" / "Disable All" button. To prevent accidental breakage, clicking a disabled language only enables it without setting it as the active language. - Select Active Language: Choose which language file to use as the active server language. Each language shows its display name, completion percentage (e.g.
English (100%),Español (96%),Čeština (42%)), and whether it is currently the active language. Click any enabled language to set it as active.
Settings that remain in the main Language category: replace_translations (auto-fill missing keys) and fallback_string (text shown for missing keys).
Translation Completion Tracking
Translator.computeCompletionPercentage() calculates each file's completion against the full 738-key TranslationKey enum. Values are recalculated on server startup, /bp reload, admin menu reload, and automatic config file watcher reload.
Translation Changes
TranslationKey.java
- 110+ new keys for dialog UI strings, organized by section
- Dialog-only settings use
_desuffix - New section keys follow config.yml structure:
LANGUAGE__LANGUAGE_FILE,PLAYERS__LOCK_ON_PLACE,BLOCKS__USE_DIALOGS_DE, etc. INVENTORIES__ENTITY__INSPECT_CONTENTSrenamed toINVENTORIES__ENTITY__INSPECT_ENTITYto fix duplicate key YAML warning.- 25 new
ICON__*keys for dialog icons (emoji/indicators), replacing hardcoded characters. All dialog icons now read from translation files.
translations_en.yml and translations_es.yml
- New
icon:section with all dialog icon/emoji keys - New
dialogs:section with all dialog UI strings - New
admin_config:subsection mirroring config.yml categories - Both files updated together. Spanish translations are natural, not literal.
- YAML indentation fixed for empty
entity:key and misindentedtransfer_not_available.
Other language files
- 13 non-EN/ES language files are now skipped at startup by default (configurable via
lang/lang.yml), eliminating all YAML parse warnings from them.
BlockProtLogger: Automatic Log File Recovery
The plugin log file (logs/blockprot-<timestamp>.log) now detects if the file is deleted or its content is cleared while the server is running. If either happens, BlockProtLogger closes the current file and creates a new one with an incrementing suffix (e.g. blockprot-2026-07-15_15-39-00_2.log), then continues writing. This prevents log data loss when cleaning or rotating logs on a live server.
All color codes (§7, §x§D§2§B§4§8§C, etc.) are stripped from the log file output, leaving clean plain text.
The startup ASCII banner now prints in a pastel coffee tone instead of pastel cyan, with a blank line before the banner and after the boot checklist to separate it from surrounding console output.
Admin Command Visibility Fix
When use_menus: true, the /bp lockables and /bp recommended commands are no longer directly executable or visible in tab-complete for players. They are only accessible through the /bp admin GUI. Tab-complete now only shows user and admin in menu mode. (/bp recommended remains console-only regardless of use_menus, since canUseCommand only permits the console sender.)
When use_menus: false (CLI mode), admin commands remain fully accessible.
Corrected during development:
about,help,info,reload,debug, andupdatewere still directly executable and visible in tab-complete even withuse_menus: true, bypassing the menu-only restriction described above. They now follow the same rule as every other individual subcommand: blocked with a usage hint and hidden from tab-complete, only reachable through/bp adminor/bp userwhile menus are enabled.
Language File Cleanup
Disabled language files (set to false in lang/lang.yml) are now deleted from the lang/ folder on reload. The completion percentage computation (updateLangCompletionPercentages()) only processes enabled languages plus the active language, instead of all registered files.
Dialog Diagnostic Logging and Auto-Disable
The plugin now detects incompatible servers and reacts automatically:
- On config reload (
reloadConfigAndTranslations): ifuse_dialogs: truebutVersionCompat.hasDialogApi()returns false (Paper < 1.21.7 or Spigot), the plugin logs theCONSOLE__DIALOGS_UNAVAILABLEwarning to both console and the log file, then callsdefaultConfig.setAndSave("use_dialogs", false)to persist the auto-disable. - On first dialog attempt (
DialogBridgeFactory.getBridge): if the bridge is still null because the API check failed, the factory logs a one-time warning suggesting the admin setuse_dialogs: falsemanually. - On reflection failure: if the
PaperDialogBridgeclass exists but fails to instantiate, the error message is logged atSEVERElevel.
Completion Percentage Format
Translation completion percentages in lang/lang.yml are now stored as YAML comments (# K: 0% instead of K: 0%), eliminating duplicate keys found: K warnings from the YAML parser.
Config.yml Cleanup
config.yml had a small cleanup pass rather than a full reorganization: the deprecated worldedit_paste_autolock block (already superseded by integrations.yml in an earlier release) was removed along with its DefaultConfig getters, the unused localized_command_aliases key was removed, and the new use_dialogs key was added next to use_menus with inline documentation. Net effect is a slightly shorter file, not a longer one.
Build & Compatibility
spigot/build.gradle.ktsupdated for the Paper dialog API dependency (rootbuild.gradle.ktswas not changed in this release).- Gradle wrapper updated from 9.6.0 to 9.6.1 (build tooling only, no runtime impact).
gradle.propertiesversion set to1.3.4with a blankversionSuffix, shipping as a normal (non-beta) release on distribution platforms like Modrinth and CurseForge..github/workflows/publish.yml: artifact upload and publishing jobs removed from CI..github/ISSUE_TEMPLATE/feature_suggestion.ymlandquestion.ymlupdated with an optional Discord-username field, an additional-context field, and the assignee changed fromspndatoVictorGugug.- README.md updated.
Bug Fixes
EntityFriendManageInventoryno longer shows "Friend cannot be removed" when the typed player name was not found. It now correctly shows "Player not found."EntityFriendManageDialogandFriendManageDialognow use the same corrected "Player not found" translation key instead of the wrong "Friend cannot be removed" message.stripColor()regex fixed to match uppercase hex color codes (§&), fixing color stripping in dialog formatting.- Hardcoded English strings in
DebugDialog,AdminConfigDialog, andUpdateDialogreplaced with translation keys. RedstoneSettingsInventoryupdated to fix interaction behavior.EntityInspectContentsInventoryandWorldLockableSelectionInventorylocalized string fixes.BlockLockInventory:INVENTORIES__ENTITY__INSPECT_CONTENTStranslation key renamed toINVENTORIES__ENTITY__INSPECT_ENTITYto fix a duplicate-key YAML warning; back button now returns to the correct menu origin instead of always closing, and the close button reads "Close" instead of "Back" when there's no origin to return to.- Lockables no longer bulk-toggle on category click: each material has its own toggle in
LockableCategoryDialog. DefaultConfig.isKeyInExpressionFormat()reversed from prior behavior: it no longer short-circuits to flat format whenmodern_family_blocks: false. It now checks each key's actual on-disk format per-key, preserving expression format when the key already uses one. This fixes individual material toggles inLockableCategoryDialogwriting verbose flat material names when the same category already uses compact family expressions like[*-SIGN]. A newconvertBlocksFileFormat()sweep re-writes every key to matchmodern_family_blocksright after the flag is flipped.HybridDatabase: log message forgetBlockIndexByWorldfailures no longer double-prefixes[BlockProt](Bukkit's logger already adds it).UpdateChecker: new constructor overload accepts anonCompletecallback, used byUpdateDialog's Check Now button to refresh the dialog in place instead of sending results to chat.BlockLockDialog: "Set Block Name" no longer closes the dialog and opens an anvil inventory. It now uses the native dialog text input with a "Confirm" save button, matching the pattern used byAdminConfigValueDialog.AdminConfigDialog: Language section split into two sub-menus (language toggle and language selector), separating enable/disable from active-language selection to make the interface clearer.DialogTextField: newconfirmLabelfield separates the text input label from the confirm button text, so the save button reads "Confirm" instead of the config key name.PaperDialogBridge.showValueInput: confirm button now usesfield.confirmLabel()instead offield.label().AboutDialog: hardcoded English labels for database engine, cache, and integrations replaced with translation keys (DIALOGS__ABOUT__DB_ENGINE_LABEL,DIALOGS__ABOUT__DB_MYSQL,DIALOGS__ABOUT__DB_SQLITE,DIALOGS__ABOUT__CACHE_LABEL,DIALOGS__ABOUT__CACHE_SUFFIX,DIALOGS__ABOUT__INTEGRATIONS_LABEL,DIALOGS__ABOUT__INTEGRATIONS_DISABLED,DIALOGS__ABOUT__INTEGRATIONS_ACTIVE).EntityEventListener,BlockEventListener(including block burn, anvil physics, and sign-change handling),ExplodeEventListener,HopperEventListener,InventoryEventListener(container open/close and access checks),PistonEventListener(push and retract),RedstoneEventListener,RaidDetectionListener: updated lockable checks to use per-world overloads, fixingRuntimeException: Given block X is not a lockable block/tile entity(such asBEE_NEST) underper_worlds_config: true./bp recommended blocks|config|all: fixed auto-reload trigger after applying configuration, now scheduling a quiet-period reload viaConfigFileWatcher.requestProgrammaticReload()that respectsauto_reload_delay_secondswhenauto_reload_configs: trueis active.
Note: owner-name-from-UUID resolution, integration double-registration handling, and localized strings in
AnvilInput/BlockInfoInventory/EntityInfoInventory/PlayerListInventory/InventoryEventListener/BlockInspectContentsInventorywere previously listed here but are not present in the 1.3.4 commit range (84f2bed..main): those files are unchanged since 1.3.3 and the claims have been removed.
Command Permissions, Lock Limits, and Configuration Fixes
The following fixes ship with 1.3.4.
Command visibility and permission gating
- The player-facing subcommands
/bp settings,/bp statistics,/bp transfer,/bp friends addall, and/bp hintsnow require theblockprot.userpermission node. Without it they are hidden from tab-complete and rejected with the permission message instead of executing./bp aboutand/bp helpare always available from the console and otherwise also requireblockprot.user. HelpCommandno longer lists admin, op-only, or debug-only entries to players who lack those permissions.- Tab-complete now checks permissions for sub-arguments as well as the first command level: completing e.g.
/bp unlock <player>no longer leaks player names to users who cannot run the command. AdminUnlockCommandgained the same permission gate as every other admin command, and the duplicate condition that made the friends entry unreachable in/bp userwas removed.
Lock-limit enforcement
- The manual lock buttons (lock menu and lock dialog) previously bypassed the configured lock limit, spawn protection, and lock events. Both now go through the regular lock path, and a failed lock shows the actual reason (e.g. "you have reached your maximum number of protected blocks") in the action bar.
Configuration fixes
worldedit.enabled(integrations.yml) is now honored: the WorldEdit paste auto-lock feature previously ignored the master toggle and only checkedworldedit.paste_autolock.enabled.fallback_string(config.yml) is now used: translation keys missing in both English and the active language previously displayed the raw key name, and now display this string instead.- The dead
blockprot.max_blockspermission node was replaced byblockprot.lockmax, with dynamicblockprot.locklimit.<N>nodes. - A config file missing the
redstone_disallowed_by_defaultkey no longer silently disables redstone interactions; it now defaults to allowing them. blocks.ymlheader comment corrected: the file can be rewritten for structural merges, format conversion, and repair.
Documentation
- The player and admin guides were updated to match the current behavior: corrected the audit log database path, the lock limit permission keys (
lockmax/locklimit.<N>), the Knowledge Book material, the shulker box admin exception, the villager workstation targeting rules, the timed-access note, and the/bp transferall <player>description. The plugin description for Modrinth and Hangar was cleaned up to remove claims that no longer apply.
Credits
- TankObliterator: proposed the Paper dialog system (Issue #1). His idea of replacing inventory/anvil/chat interactions with Minecraft's native dialog API became the central feature of this release.
Language Maintenance Policy
Only English (translations_en.yml) and Spanish (translations_es.yml) are actively maintained by the author. The other 18 bundled language files (13 community-contributed languages cs, de, fr, it, ja, ko, pl, pt-br, ru, sk, tr, zh-cn, zh-tw, plus 5 empty templates hu, nl, th, fi, id) are not modified by the author between releases. Missing keys fall back to English automatically.
Known Issues
- Dialog system requires Paper 1.21.7+. Falls back to legacy inventories on Spigot or older Paper.
use_dialogsanduse_menusinteraction: whenuse_dialogs: true, all interfaces use dialogs regardless ofuse_menus. Whenuse_dialogs: false, behavior is unchanged from prior versions.ReloadCoordinator.executeReloadcaptures the "before" snapshot from the plugin's live in-memory config forAUTOMATIC/EXTERNAL_FILEsources instead of re-reading disk, since by that point the external edit has already landed on disk for both reads.- When
auto_reload_configs: false, an external file edit or dialog change is written to disk but not applied automatically; it takes effect on the next manual reload or server restart. No in-chat preview of the pending change is shown in this mode.
Language File Maintenance
Cleaned up stale language files and added five new bundled language templates:
- Removed 43 orphaned keys from the 13 stale translation files (cs, de, fr, it, ja, ko, pl, pt-br, ru, sk, tr, zh-CN, zh-TW). These referenced removed features (pets, land claims, wand system, webhook dispatcher).
- Hungarian (translations_hu.yml), Dutch (translations_nl.yml), Thai (translations_th.yml), Finnish (translations_fi.yml), and Indonesian (translations_id.yml) added as bundled language templates, sourced from community draft templates. They ship in the JAR and are listed on GitLocalize, but are not yet registered in
Translator.DEFAULT_TRANSLATION_FILESorlang/lang.yml, so they are not selectable or loadable at runtime yet (staged for 1.3.5). Empty templates; all keys fall back to English. - All 18 non-EN/ES bundled language files now carry the complete key set of the English reference (880 keys). Newly added keys are blank in community languages and in the templates, and blank values fall back to English; no translation was written for any community language in this pass. The legacy quoted
'True'/'False'keys and the staleconsole.recommended_donekey were removed from the 13 community files. - Spanish (translations_es.yml) brought to full parity with the English reference. 32 missing keys in the admin config section were added with natural Spanish translations.
- Translations now hosted on GitLocalize for community contribution, including Finnish (fi) and Indonesian (id).
Files
Verified against git diff --stat a8c7c867..HEAD (31 commits, 84f2bed through eaa0b36, the full 1.3.4 development range following the 1.3.3 release commit a8c7c867). 145 files touched. Files that were unchanged in this range have been removed from the lists below even where an earlier draft of these notes attributed 1.3.4 work to them.
New Files
Dialog infrastructure:
spigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogBridge.javaspigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogBridgeFactory.javaspigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogBodyEntry.javaspigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogOrigin.javaspigot/src/dialogs/java/de/sean/blockprot/bukkit/dialogs/impl/PaperDialogBridge.java: confirm button now usesfield.confirmLabel()instead offield.label()spigot/src/main/java/de/sean/blockprot/bukkit/config/LangConfig.javaspigot/src/main/java/de/sean/blockprot/bukkit/config/ReloadCoordinator.javaspigot/src/main/java/de/sean/blockprot/bukkit/config/ReloadReport.javaspigot/src/main/java/de/sean/blockprot/bukkit/logger/PluginActivityLog.javaspigot/src/main/java/de/sean/blockprot/bukkit/listeners/EffectGeometry.java
Dialog screens:
AboutDialog.java,AdminConfigDialog.java(Language section split into two sub-menus),AdminConfigValueDialog.java(save button label fix),AdminMenuDialog.java,AuditDialog.java,AutoDropDialog.java,AutoDropFamilyDialog.java,BlockInfoDialog.java,BlockLockDialog.java(set block name uses dialog text input instead of anvil),BlockSettingsDialog.java,DebugDialog.java,EntityBlockSettingsDialog.java,EntityFriendManageDialog.java,EntityInfoDialog.java,FriendManageDialog.java,InfoDialog.java,IntegrationsDialog.java,LockableCategoryDialog.java,LockablesDialog.java,ProtdelDialog.java,StatsDialog.java,UnlockDialog.java,UpdateDialog.java,UserMenuDialog.java,UserSettingsDialog.java(all underspigot/src/main/java/de/sean/blockprot/bukkit/dialogs/)
Dialog utilities:
spigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogButton.javaspigot/src/main/java/de/sean/blockprot/bukkit/dialogs/DialogTextField.java: newconfirmLabelfield separates input label from confirm button text
Commands:
spigot/src/main/java/de/sean/blockprot/bukkit/commands/DebugCommand.java
Resources:
spigot/src/main/resources/lang/lang.ymlspigot/src/main/resources/lang/translations_hu.yml: new Hungarian translation templatespigot/src/main/resources/lang/translations_nl.yml: new Dutch translation templatespigot/src/main/resources/lang/translations_th.yml: new Thai translation templatespigot/src/main/resources/lang/translations_fi.yml: new Finnish translation templatespigot/src/main/resources/lang/translations_id.yml: new Indonesian translation templateimages/RELEASE TITLES/R_N/RELEASE_NOTES_1.3.4.png
Docs:
docs/RELEASE_NOTES/1.3.4.RELEASE_NOTES.md: this filedocs/MODERN SYNTAX AND LEGACY/BLOCK_FAMILY_SYNTAX.md: removed decorative separatorsdocs/MODERN SYNTAX AND LEGACY/LOCKABLE_BLOCKS_REFERENCE.md: removed decorative separators, replaced non-ASCII characters
Removed from this list (pre-existing since 1.3.3 or earlier, confirmed via
git ls-tree a8c7c867):ResidenceIntegration.java,GriefPreventionIntegration.java,ClaimChunkIntegration.java,IntegrationConfig.java,integrations.yml.
Modified Files
Commands:
AboutCommand.java,AdminMenuCommand.java,AdminUnlockCommand.javaBlockProtCommand.java: admin commands blocked in menu mode; tab-complete hides admin commands when menus enabledRecommendedCommand.java: split into independentblocks/config/allhalves with per-half applied flags and aforceargument;AdminUnlockCommand.java:canUseCommandgateFriendsAddAllCommand.java,InfoCommand.java,IntegrationsCommand.java,LockablesCommand.java,SettingsCommand.java,StatisticsCommand.java,UserMenuCommand.java,WorldProtDeleteCommand.javaHelpCommand.java,HintsCommand.java,TransferCommand.java: gated behindblockprot.user;HelpCommand.javano longer lists entries the sender lacks permission forReloadCommand.java: routed throughReloadCoordinatorUpdateCommand.java: uses the newUpdateCheckeronCompleteoverload
Config and infrastructure:
spigot/src/main/java/de/sean/blockprot/bukkit/config/DefaultConfig.java: 20+ setters;auto_reload_delay_secondsgetters and setters;isKeyInExpressionFormat()per-key format fix; newconvertBlocksFileFormat()sweep; bed materials recognized as lockable blocks; per-material and per-family auto-drop toggle methods for the new Auto Drop dialogs;disallowRedstoneOnPlace()no longer defaults to disallowing redstone when the key is missing fromconfig.yml;blocks.ymlheader comment correctedspigot/src/main/java/de/sean/blockprot/bukkit/config/BlockFamilyParser.java: added a BED sub-familyspigot/src/main/java/de/sean/blockprot/bukkit/nbt/BlockNBTHandler.java: bed halves are treated as a merged unit, the same way double chests already are; lock-limit exemption check usesPermissions.LOCKMAX.key()instead of the hardcodedblockprot.lockmaxstringspigot/src/main/java/de/sean/blockprot/bukkit/util/BlockUtil.java: newgetOtherBedHalf()helperspigot/src/main/java/de/sean/blockprot/bukkit/config/ConfigFileWatcher.java: refactored to generation-based quiet-period scheduler with route-based suppression;requestProgrammaticReload()used directly byDefaultConfig.setAndSave()and blocks.yml savesspigot/src/main/java/de/sean/blockprot/bukkit/BlockProt.java: dialog init; lang cleanup; logger initspigot/src/main/java/de/sean/blockprot/bukkit/BlockProtLogger.java: color code stripping; Java logger mirror Handler; mandatory activity loggingspigot/src/main/java/de/sean/blockprot/bukkit/BlockProtConsole.java: pastel color palette applied to the startup banner and boot checklist (coffee-tone banner, active/inactive status dots); blank lines added before the banner and after the boot checklist; boot lines now route throughBlockProtLoggerspigot/src/main/java/de/sean/blockprot/bukkit/Permissions.java:blockprot.max_blocksrenamed toblockprot.lockmax(kept as a deprecated alias); newblockprot.locklimit.<N>dynamic node documentedspigot/src/main/java/de/sean/blockprot/bukkit/VersionCompat.java: dialog API version check (hasDialogApi())spigot/src/main/java/de/sean/blockprot/bukkit/TranslationKey.java: new dialog keys; a dedicated_TITLEdisplay-name key for every admin config setting, separate from its longer tooltip description; Placements keys; 8 new About dialog keys for database engine, cache, and integrations labelsspigot/src/main/java/de/sean/blockprot/bukkit/Translator.java: completion-percentage computation; missing translation keys now fall back to the configuredfallback_stringinstead of the raw key namespigot/src/main/java/de/sean/blockprot/bukkit/nbt/StatHandler.java: minor fixspigot/src/main/java/de/sean/blockprot/bukkit/nbt/stats/LocationListEntry.java: block title now includes the world name alongside coordinatesspigot/src/main/java/de/sean/blockprot/bukkit/nbt/PlayerSettingsHandler.java: new per-playerblockprot_prefer_dialogspreference (getPreferDialogs()/setPreferDialogs()), defaulting to the server'suse_dialogssettingspigot/src/main/java/de/sean/blockprot/bukkit/storage/HybridDatabase.java: removed duplicate[BlockProt]log prefixspigot/src/main/java/de/sean/blockprot/bukkit/tasks/BackupTask.java: javadoc backup path updated to theplugins/BlockProtReloaded/backups/folderspigot/src/main/java/de/sean/blockprot/bukkit/tasks/UpdateChecker.java: newonCompletecallback overload forUpdateDialog
Listeners:
InteractEventListener.java: routes toBlockLockDialogwhenuse_dialogs: trueLockEffectListener.java: updated to useEffectGeometryperimeter particle samplingInventoryEventListener.java,BlockEventListener.java,PistonEventListener.java,RedstoneEventListener.java,HopperEventListener.java: lockable checks now use the per-world-aware overload so they agree withBlockNBTHandler, fixing aRuntimeExceptionon container open underper_worlds_config: trueWorldEditPasteListener.java: now checksworldedit.enabled(integrations.yml) in addition toworldedit.paste_autolock.enabledbefore auto-locking a pasteItemFrameListener.java,VehicleProtectionListener.java: dialog-mode handling
Inventories:
AdminMenuInventory.java,UserSettingsInventory.java: dialog routingUserMenuInventory.java: dialog routing; Statistics slot renamed to PlacementsBlockLockInventory.java: back-button now returns to correct menu origin;INSPECT_ENTITYkey rename; manual lock button now goes through the regular lock path (limit, spawn protection, lock events), showing the actual reason on failureRedstoneSettingsInventory.java: interaction fixEntityFriendManageInventory.java: "Player not found" message fixEntityInspectContentsInventory.java,WorldLockableSelectionInventory.java: localized string fixesWorldLockableDetailInventory.java: requests a programmatic quiet-period reload via the config file watcher after saving a per-world change toworlds.ymlLockablesInventory.java,AutoDropInventory.java,AutoDropFamilyInventory.java:NamedTextColorreplaced with the pastel color palette used elsewhere in the plugin
Dialogs:
AdminConfigDialog.java: added Reload configuration button,auto_reload_delay_secondssetting; buttons now show a short display name with the description and raw config key moved into the tooltipAdminMenuDialog.java: Reload button runs an immediate reload and reports success or failure in chatAboutDialog.java: hardcoded English labels replaced with translation keys (db engine, cache, integrations); pastel color theme appliedBlockLockDialog.java: pastel color theme applied; lock button now goes through the regular lock path (limit, spawn protection, lock events), showing the actual reason on failureAuditDialog.java,BlockInfoDialog.java,BlockSettingsDialog.java,DebugDialog.java,EntityBlockSettingsDialog.java,EntityFriendManageDialog.java,EntityInfoDialog.java,FriendManageDialog.java,InfoDialog.java,IntegrationsDialog.java,LockableCategoryDialog.java,LockablesDialog.java,ProtdelDialog.java,UnlockDialog.java,UpdateDialog.java,UserSettingsDialog.java: pastel color theme applied to all dialog screensAdminConfigValueDialog.java: pastel color theme applied; dialog title and input field label now use the short display name instead of the raw config keyStatsDialog.java: pastel color theme applied; addedshowUserStats()for the Placements screen (limit display, no global toggle, click a block to edit it directly)UserMenuDialog.java: pastel color theme applied; Statistics button renamed to Placements, routed toshowUserStats()DialogBridge.java,DialogBridgeFactory.java,DialogBodyEntry.java,DialogOrigin.java,DialogButton.java,DialogTextField.java: dialog infrastructure and utilitiesspigot/src/dialogs/java/de/sean/blockprot/bukkit/dialogs/impl/PaperDialogBridge.java: pastel color theme applied
Resources:
- 13 stale
translations_*.ymlfiles: orphaned keys removed (43 keys referencing removed features); later completed to the full English reference key set (64 dialog and admin-config keys added per file, blank until community-translated); the legacy quoted'True'/'False'icon keys and the staleconsole.recommended_donekey removed translations_en.yml,translations_es.yml: auto reload delay and pending reload review keys added; short_TITLEdisplay-name strings for admin config buttons; Placements stringstranslations_hu.yml,translations_nl.yml,translations_th.yml,translations_fi.yml,translations_id.yml: bundled language templates, regenerated in the English reference key orderspigot/src/main/resources/config.yml: addedauto_reload_delay_secondsunder Maintenance; cleanupspigot/src/main/resources/blocks.yml: header comment updated for the/bp recommended blockssplit;auto_drop_to_inventory.blocksnow ships with two blank template lines like every other lockable list instead ofblocks: []spigot/src/main/resources/worlds.yml: header comment punctuation cleanupspigot/src/main/resources/plugin.yml: dialog API dependency;blockprot.max_blockspermission renamed toblockprot.lockmax, new dynamicblockprot.locklimit.<N>node added
Build and CI:
spigot/build.gradle.kts: Paper dialog API dependencygradle.properties: version set to 1.3.4 with a blankversionSuffix(normal, non-beta release).github/workflows/publish.yml: artifact upload/publishing jobs removed.github/PLATFORM_DESCRIPTION.md: session log path updated to theplugins/BlockProtReloaded/logs/folder.gitignore,README.md,.gitlocalize.yml: README language lists updated for the 20 bundled files (fi and id added to the GitLocalize languages);.gitlocalize.ymlsynchronize sources extended totranslations_fi.ymlandtranslations_id.yml
Docs:
docs/RELEASE_NOTES/1.3.3.RELEASE_NOTES.md: "Coming next" section updated to point at these notesdocs/MODERN SYNTAX AND LEGACY/BLOCK_FAMILY_SYNTAX.md: decorative separator and punctuation cleanupdocs/MODERN SYNTAX AND LEGACY/LOCKABLE_BLOCKS_REFERENCE.md: decorative separator and punctuation cleanupdocs/MODERN SYNTAX AND LEGACY/LEGACY_BLOCKS_SYNTAX.md: updated for the/bp recommended blockssplit and added links to the admin/player guidesdocs/READ_MEs/MODR_HANG_README.md: Modrinth/Hangar plugin description cleaned up to remove claims that no longer apply; language row updated to the 20 GitLocalize languages
Language file maintenance pass: the 13 community translation files now carry the complete English reference key set (64 dialog and admin-config keys added per file, blank until community-translated), and the five template files were regenerated in the English reference key order. Verified against the working-tree
git diff(changes uncommitted at the time of writing) plus a programmatic key-parity check againsttranslations_en.ymlon every bundled file (880 keys each, no missing, no orphan, no duplicate) and YAML parsing validation.
Removed from this list (pre-existing since 1.3.3 or earlier, unchanged in this commit range): IntegrationConfig.java, BlockProtAPI.java, SkinCache.java, BlockProtInventory.java, BlockInfoInventory.java, AnvilInput.java, EntityInfoInventory.java, PlayerListInventory.java, BlockInspectContentsInventory.java, PluginIntegration.java, LandsPluginIntegration.java, WorldGuardIntegration.java, TownyIntegration.java, PlaceholderAPIIntegration.java, ViaVersionIntegration.java, integrations.yml, root build.gradle.kts, .github/ISSUE_TEMPLATE/bug_report.yml.
Corrected: BlockNBTHandler.java, HopperEventListener.java, PistonEventListener.java, InventoryEventListener.java, WorldEditPasteListener.java, BlockProtConsole.java, and HelpCommand.java were previously listed above as unchanged. All seven were actually modified within the a8c7c867..HEAD range and are listed in their correct sections below.
Looking Ahead to 1.3.5: Language Snapshots
Starting in 1.3.5, each new language contributed by the community will be distributed as an independent snapshot resource rather than bundled into the plugin JAR. This means:
- Languages can be added, updated, or removed without waiting for a full plugin release.
- Community translators maintain their own language files independent of the release cycle.
- The plugin will load external language files from the
lang/folder, and any missing keys fall back to the bundled English reference. - If you want to contribute a new translation or update an existing one, look for the language snapshot releases on the Releases page.
This change reduces the plugin JAR size, eliminates YAML warnings from incomplete community translations, and lets the community drive language support at their own pace.
