File Details
CustomJukebox-3.2.0.jar
- R
- Jul 12, 2026
- 235.65 KB
- 7
- 26.2+11
File Name
CustomJukebox-3.2.0.jar
Supported 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
[3.2.0] - 2026-07-12
Added
- Configurable "Now Playing" announcements: the title shown in the center of the screen and the actionbar message when a custom disc starts can now be disabled individually via
playback.show-titleandplayback.show-actionbarinconfig.json(both default totrue, matching previous behavior). - Automatic config merging: on load,
config.jsonanddisc.jsonare compared against the plugin's bundled defaults and any keys introduced by a newer version are added automatically, without overwriting existing values. New options (like theshow-*flags above) now appear in existing config files after an update/reloadinstead of having to be added by hand. Indisc.jsonthediscs/categories/playlistssections are treated as user content and are never re-seeded with the default examples, so deleted example discs do not reappear. - Configurable backup count: the number of timestamped
config/discbackups kept is now set viasettings.max-backups(default5, same as before). Set it to0to disable backups entirely — existing backup files are then pruned on the next save. Values are clamped to a maximum of 100. Previously the count was hard-coded to 5.
Fixed
- GUI system rebuilt on InventoryHolder: All plugin GUIs (Admin panel, disc/category/playlist editors, jukebox disc GUI) are now identified via a custom
InventoryHolderinstead of window titles and per-player context maps. This fixes a family of serious bugs:- Closing a GUI with ESC no longer leaves a stale session that hijacked clicks in chests/containers opened afterwards (previously this could overwrite real chest contents with GUI items and spawn free disc copies via the delete-confirmation dialog).
- Opening the playlist editor or disc editor from the admin panel no longer breaks their click handling (the close event of the previous menu wiped the new context).
- The same click is no longer processed by two GUIs at once (admin panel + disc editor).
- The jukebox disc GUI no longer depends on a lossy title round-trip — hex/gradient
gui-titlevalues previously broke the comparison and made GUI items freely extractable. /cjb guiuses the same holder-tagged inventory, and all GUI click handlers cancel the click before any session/permission checks, so a missing session can never make GUI items extractable.
- Item safety in GUIs:
InventoryDragEventis now cancelled in all GUIs (items could previously be dragged into a GUI and lost), and collect-to-cursor double-clicks can no longer pull items out. - Logout cleanup: All GUI/wizard sessions are cleared on player quit. Previously a player who logged out mid-wizard had every chat message swallowed and processed as wizard input after rejoining.
- Folia: auto-stop/loop tasks are now cancellable:
SchedulerUtilreturns a platform-independentTaskHandle(wrapping Folia'sScheduledTask.cancel()). Stale auto-stop tasks could previously stop a newer playback at the same jukebox (e.g. disc B stopped mid-song at disc A's old end time), and orphaned loop tasks multiplied. Tasks additionally verify they still belong to the same playback session when firing. - Playlists survive volume/mute restarts:
/cjb mute,/cjb unmuteand/cjb volume <x> restartno longer wipe the running playlist queue (playback previously went silent after the current track). - Skeleton-kill fragment drops actually work: the guaranteed drop when a skeleton kills a creeper never triggered (
getKiller()only returns players). Now resolved via the last damage cause, including arrows, covering Skeleton/Stray/Bogged. - Off-hand discs are recognized: interaction handlers now use the hand that triggered the event. Off-hand discs previously got inserted by vanilla without the custom sound; the GUI also opened twice. With the GUI enabled, an off-hand disc now takes priority over opening the GUI.
- Ejecting by disc swap stops the sound: right-clicking an occupied jukebox while holding another disc lets vanilla eject the record — the custom sound now stops with it (previously it kept playing over the empty jukebox).
- Hopper support: a hopper extracting the disc stops the custom sound (it previously played to the end); a hopper inserting a custom disc starts the custom sound. Extraction is verified one tick later so transfers cancelled by protection plugins don't cut the music.
- Disc identity via PersistentDataContainer: disc and fragment items now carry their ID in the PDC. Two discs sharing the same CustomModelData are no longer confused when editing/deleting/giving (legacy items still match by model data). Note: deleting a disc and recreating it under a new ID invalidates already-issued items of the old ID — they intentionally no longer match by texture alone.
- Thread-safety on Folia: disc/category/playlist/language registries are now
ConcurrentHashMap(a/cjb reloadcould previously throwConcurrentModificationExceptionin event handlers on other region threads);UpdateCheckerresults, mute state and playback flags arevolatile;onDisableno longer calls the Bukkit scheduler on Folia (threwUnsupportedOperationException). - config.json saves atomically (temp file + atomic move, like disc.json) and
/cjb reloadreloads the persisted mute state. - Validation restored: disc/category/playlist IDs must be
[A-Za-z0-9_-]+(IDs with spaces were previously creatable but unusable in commands); sound keys are validated as resource locations again — the wizard's error messages for these cases were dead code. - Gradients fixed:
<gradient:#RRGGBB:#RRGGBB>was destroyed by the hex pre-pass inAdventureUtiland never rendered; hex colors are no longer downsampled to legacy codes on serialization. /cjb volume: tab-completion no longer suggests locale-formatted values like0,5that the parser rejects;NaNno longer passes the range check.- Permission
customjukebox.fragmentis now actually checked by/cjb fragment(previously it requiredcustomjukebox.give, and the declared node was dead). Migration note: servers that grantedcustomjukebox.givedirectly (not viacustomjukebox.admin) must additionally grantcustomjukebox.fragmentto keep/cjb fragmentaccess. - Playback tracking leak: discs without a configured duration no longer leave a tracking entry behind forever (fallback cleanup after 1 hour);
loopwithout a duration now logs a warning instead of being silently ignored. - Orphan cleanup: deleting a disc removes it from all playlists; deleting a category detaches it from its discs.
- Deleting playlists/categories in the admin panel now requires a confirming second right-click (they were previously deleted instantly and irreversibly); failed deletions report an error.
- Chat-input hardening: input modes are consumed atomically (rapid double messages were processed twice), the disc editor's chat handler respects cancelled events, and all chat/wizard handlers re-check the admin permission before applying input.
- Log hygiene: per-click and per-playlist-progression INFO logs are now behind the debug flag.
Changed
ParrotDanceListenerno longer schedules hundreds of empty per-parrot tasks (the vanilla dance animation cannot be forced via the Bukkit API); it now shows a short note-particle burst above nearby parrots instead.
Performance
- Fewer disk writes on delete: deleting a disc or category now rewrites
disc.jsona single time instead of once per affected playlist/disc (each of which previously also created a backup and scanned the backup directory). - Folia scheduler: reflection handles are resolved once against the public scheduler interfaces and cached, instead of being looked up on every schedule/cancel call on the playback hot path.
- Cheaper event hot paths: hopper transfers are filtered by item/inventory type before any block-state lookup, and GUI event handlers use a non-snapshotting holder check — so hopper-heavy servers and players interacting with vanilla containers no longer pay for block-entity snapshots on every event.