BS CustomJukebox
3.7.0Fully-featured Paper 1.21.x, 26.x jukebox plugin with custom music discs, disc fragments, GUI support, and WorldGuard/GriefPrevention integration.
3.7.0latestBS CustomJukebox 3.7.03 weeks ago [3.7.0] - 2026-10-02
Added
- Point-source zones (/cjb zone source <zone> point): music plays from the zone center, fades with distance and is not cut off when leaving. Optional; zones default to the previous behaviour. - Zone jukebox (/cjb zone jukebox <zone>): a placeable jukebox the zone plays from, with note particles; break it to move the zone. - Update notice for operators with clickable Modrinth and CurseForge links.Fixed
- Fragment crafting no longer duplicates discs. - Unreadabledisc.json,zones.json,config.json,players.jsonor language files are kept and no longer overwritten. -/cjb skiponly skips playlists and zones; ending a single disc needscustomjukebox.stop. Favourites needcustomjukebox.playlistfor wider ranges. - Trail ruins now actually drop fragments when brushed. - Various fixes to shutdown, world unloading, Folia thread safety, GUI chat input and input validation.3.6.0BS CustomJukebox 3.6.0Aug 31, 2026 [3.6.0] - 2026-08-31
Added
- Volume in decibels for the server, zone and personal commands:-6dbis half,-12dba quarter,-20dba tenth — easier to judge by ear than the linear scale, where 0.5 does not sound half as loud. - Presets and percentages for zone and personal volume too, not just the server one:silent,quiet,normal,loud,maxand values such as30%. - Volume feedback names what it did —0.30 (30%, -10.5 dB)— and warns above 1.0 that the sound is already at full loudness and only carries further, since Minecraft widens the radius (volume * 16blocks) rather than raising the gain. - `/cjb zone volume <zone> <value> norestart`, to let the current track finish at its old volume. - `ambient-zones.pause-during-disc`, to keep discs and zone music layered.Changed
- All three volume commands share one parser, so their presets and ranges cannot drift apart. - The author prompt in the disc editor shows the formatting example itself, instead of pointing at the display name prompt that whoever opens the author field first never sees. - Editor titles drop the namespace prefix a server's disc ids share:Edit: music_disc.newbeginnings_themebecomesEdit: newbeginnings_theme. The prefix is read from the ids in use rather than assumed, socustom.or a multi-level one works the same; where ids do not all share one, nothing is stripped.Fixed
- Colour codes in a disc's author field were printed instead of applied —&eArtistreached the tooltip as the literal text<yellow>Artist. Legacy codes are now recognised with either marker (&or§) and in either case, so hex and gradients survive as well. The same fix covers everywhere else the two markers were mixed: fragment lore, the jukebox subtitle, GUI text. - A disc and an ambient zone played over each other. The zone now falls silent for the listeners who can hear a disc and returns when it ends — not between the tracks of a playlist, where the next one starts immediately. - A zone's own volume followed the server volume for anyone with a personal volume set: at the shipped server volume of 4.0, a zone at 0.2 collapsed to a twentieth of the player's setting. An explicit zone volume is absolute now; only zones oninheritfollow the server. - `/cjb music volume` did nothing until the current track ended — minutes, on a looping zone. It restarts what that one player hears, immediately. - `/cjb volume ... restart` ignored ambient zones, restarting jukebox playbacks only. The same applied to/cjb muteand/cjb unmute. - `norestart` had no effect, because saving a zone restarted it before the flag was read. - Tab completion offered no quiet value./cjb zone volumesuggestedinherit, 1, 2, 3, 4, and since 1.0 is already full loudness, turning a zone down reliably ended at 1 and stayed loud. - `/cjb volume` looked broken to an admin with a personal volume set, which replaces the server volume rather than scaling it. The command now says which value wins and how to undo it. - Chat confirmations printed the markup they had just applied, while the item itself came out correctly coloured. - Long names ran past the edge of the GUI — admin panel entries and all five editor titles are shortened now, measured in visible characters so a gradient's tags are not cut in half. The disc item players receive keeps its full name. - Language files never gained messages added after they were first written; one long-running server was missing 170 of its 226. Missing messages are written in on every start, strictly additively — existing lines and comments are untouched.3.5.0BS CustomJukebox 3.5.0Aug 25, 2026 [3.5.0] - 2026-08-26
Added
- Per-player sound delivery hooks —CustomSoundPlayEventandCustomSoundStopEvent, both cancellable, fire once per player immediately before a custom disc sound is sent or stopped. Every delivery path passes through them: jukebox playback, a listener attaching to a running playback,/cjb music on, and ambient zones (including radio). Companion plugins that need to deliver a sound differently for some players — the Bedrock extension speaks a different sound namespace — cancel the event and play it themselves. Cancelling suppresses only that one sound packet; the player stays a tracked listener, so progress bar,/cjb skipand stop handling keep working for them. - Disc items now carry their disc id as a `custom_model_data` string tag in addition to the existing float. Java resource packs are unaffected (they select models by the float); the string gives Geyser an exact, unambiguous key to match a Bedrock item against, which a float threshold cannot provide. Disc items handed out before this version keep working but lack the tag — re-issue them with/cjb giveif Bedrock textures matter.3.4.0BS CustomJukebox 3.4.0Aug 20, 2026 [3.4.0] - 2026-08-16
Added
- `/cjb skip` — skips the track you are currently hearing. Resolves the source the same way the progress bar does: an ambient zone you are standing in takes precedence over a jukebox you are merely in range of. In asyncedzone the whole zone advances; in anindividualzone only your own cursor moves on. There is deliberately no "previous track": a resource-pack sound can only be started from its beginning, so going back would just be skipping forward through the rest of the playlist. - Progress bar — a boss bar showing the current track and how far into it you are, for jukeboxes, zones and radio alike. The elapsed time is the plugin's own bookkeeping (the server never learns the client's real playhead), which is exact for anyone present when the track started. Configurable viaplayback.show-progress-barandplayback.progress-update-ticks. This finally uses the timing methodsJukeboxPlaybackhas carried unused since 1.x. - Shuffle and repeat modes for playlists:/cjb playlist play <id> [shuffle] [loop|repeat-one|off], order-independent. Shuffling reshuffles on every lap (and avoids repeating a track across the wrap) so a looping playlist is not one fixed sequence forever. - Shuffle for ambient zones:/cjb zone shuffle <id> <true|false>, plus a toggle in the zone editor GUI. - Server radio — a new zone type that reaches every player in every world:/cjb zone global <id>. It reuses the whole zone machinery, so a radio station has the same playlist, loop, shuffle, playback mode and volume options, and a local zone with a higherprioritystill overrides it for players standing inside that zone. - Personal music settings (/cjb music, permissioncustomjukebox.music, default true):on/off/toggleto opt out of plugin music entirely,volume <0-4|reset>for a personal volume, andstatusto see your settings plus what is currently playing. Both persist across sessions in a newplayers.json. A personal volume replaces the server volume rather than scaling it, so it stays predictable when an admin changes the global value; a server-wide/cjb mutestill wins. Turning music off silences the current track immediately rather than at its end. - Favourites (/cjb favorite, permissioncustomjukebox.favorite, default true):add/remove/toggle/list/clear, andplay [shuffle] [loop|repeat-one] [global|world|<radius>]to play them as an ad-hoc playlist. Discs can also be favourited by shift-clicking them in the disc menu, which shows a ★ for entries already on the list.Fixed
- `/cjb music on` stayed silent until the next track. A jukebox/playlist listener set is only filled when a track starts, and turning music off removed the player from it - nothing put them back mid-track. Re-enabling now re-attaches immediately: zones re-evaluate in the same tick instead of at the next scan, and any playback within earshot starts for that player. The track necessarily restarts from its beginning for them (the sound engine cannot seek), which the plugin now says out loud instead of leaving it to be discovered. - `/cjb skip` reported "nothing playing" when something clearly was. It resolved the playback strictly by listener membership, so a player who had just re-enabled their music - or who walked up after the track started - was told there was nothing to skip. Skip now resolves by earshot, preferring what the player actually hears and falling back to what is playing in range. - Both were found within minutes of the first real in-game test, and both traced back to the same root: listener sets are only populated at track boundaries.Changed
- `/cjb playlist play` and `/cjb favorite play` accept a playback range:[global|world|<radius>], the same vocabulary/cjb playalready used. The queue stored a range all along and passed it to every following track - only the command never exposed it, so playlists were locked tonormal. For permanently server-wide music a radio zone (/cjb zone global) remains the better tool; a global-range playlist is a one-off from your position. - `all` is no longer a repeat-mode alias. It means "server-wide range" in/cjb play, and now that the play commands accept both kinds of flag it would have meant two different things depending on the command.loop,trueandyesstill select repeat-all.Notes
- Volume changes — personal or server-wide — apply from the next track. A sound already handed to the client cannot be adjusted, only restarted. -players.jsononly stores players who actually changed something; entries that are all-default are dropped on save.3.3.0BS CustomJukebox 3.3.0Jul 20, 2026 [3.3.0] - 2026-07-19
Added
- Ambient zones — auto-playing looping playlists for regions/areas: a zone continuously loops a playlist and starts automatically for every player who enters its area, with no disc or command needed once configured. Ideal for lobby/hub background music or event ambience. Zones are stored in a newzones.jsonand managed via/cjb zone(permissioncustomjukebox.zone, default op) or the/cjb zone edit <id>GUI. - Three area types: a radius around a point (no dependencies), a named WorldGuard region (/cjb zone region <id> <region>), or a cuboid box between two corner positions (/cjb zone pos1 <id>//cjb zone pos2 <id>, covering the full block range between them like a WorldGuard selection). Overlapping zones resolve bypriority(highest wins). - Height range (/cjb zone height <id> <full|limited>): by default (full) a zone ignores the Y axis — a radius zone is a vertical cylinder and a cuboid an infinite column, so players hear it at any height within the horizontal footprint.limitedbounds the zone in Y too (a true 3D sphere/box). Defaults tofullso lobbies aren't limited to a few blocks of vertical range. - Whole-playlist loop: each zone loops its playlist back to the first track at the end. - Per-zone playback mode (/cjb zone playback <id> <synced|individual>): -synced(default): one shared timeline — everyone in the zone hears the same track at the same time. Best for events. Late arrivals are handled by two sync modes (/cjb zone sync <id> <immediate|next_track>):immediatestarts the current track from its beginning for a player who walks in mid-track (never silence, slightly offset);next_trackwaits for the next track boundary so they join perfectly in sync. This is because Minecraft's sound engine cannot seek — a running track cannot be joined at its exact current position; everyone re-syncs at each track boundary regardless. -individual: each player runs the playlist on their own from the moment they enter, always hearing complete tracks start-to-finish (no mid-song switching), looping the whole playlist — but not in sync with other players. Best for lobby/background music.syncModedoes not apply here. - Per-zone options:playlist,loop,playback,syncMode,fullHeight(see Height range),volume(inheritor 0–4, controlling audible radius),priority,enabled. Set via subcommands or the editor GUI;/cjb zone radius|center,pos1|pos2andregionshape the area from your position. - Config: master switchambient-zones.enabledinconfig.json; scan cadencesettings.scan-interval-ticksinzones.json(default 20 ticks). A single scanner assigns players to zones each interval. - Folia-safe: the scanner dispatches each player's evaluation and sound playback to that player's region thread; a new global scheduler path inSchedulerUtildrives the per-zone (and per-player, inindividualmode) track timers. Discs without a configured duration are skipped in zones (a zone needs durations to advance/loop).3.2.0BS CustomJukebox 3.2.0Jul 12, 2026 [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 viaplayback.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 timestampedconfig/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 customInventoryHolderinstead 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/gradientgui-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 nowConcurrentHashMap(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.fragment` is 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 rewritesdisc.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, and3.1.0BS CustomJukebox 3.1.0Jul 4, 2026 [3.1.0] - 2026-07-04
Changed
- Unified release: The 2.x (Minecraft 1.21.x) and 3.0.0 (Minecraft 26.x) lines are merged into a single version. One jar now supports Paper/Folia 1.21.4 through 26.x. - Built against Paper API 1.21.4 withapi-version: '1.21'and Java 21 bytecode — loads on 1.21.4+ servers (Java 21) and 26.x servers (Java 25) alike. - Contains all fixes from the 2.x line (2.1.5–2.2.1) plus the 3.0.0 modernizations (component-based CustomModelData, metadata API replacement). - Example resource pack:max_formatraised to[84, 0]so the pack is accepted by Minecraft 26.x clients (format 84) while staying compatible with 1.21.9+. - Debug logging: Volume debug output now includes distance, sound/player coordinates, world check, and estimated max range to help diagnose audibility issues.Fixed
- Debug logging: Cross-world distance calculation no longer throws an exception when aGLOBALplayback reaches players in other worlds (previously triggered a misleading "FAILED TO PLAY SOUND" error with debug mode enabled). Distance is now logged asN/A (different world)instead. - Debug logging: Numbers are formatted locale-independently (always12.5instead of12,5on e.g. German systems).3.0.0BS CustomJukebox 3.0.0May 6, 2026 [3.0.0] - 2026-05-02
Added
- Public API Events: New event system for companion plugins -DiscPlaybackStartEvent— Cancellable event fired when a disc starts playing. Exposes disc, location, and mutable listener set. -DiscPlaybackStopEvent— Fired when playback stops, withStopReasonenum (MANUAL, DURATION_END, BLOCK_BREAK, PLUGIN). -DiscRegisteredEvent— Fired when a new disc is created via GUI or config. -DiscRemovedEvent— Fired when a disc is removed, includes a snapshot of the deleted disc. - API method:CustomJukeboxAPI.getPluginDataFolder()— Allows companion plugins to locate disc sound files.Changed
- PlaybackManager: Now firesDiscPlaybackStartEventbefore playing sounds (allows cancellation and listener modification) andDiscPlaybackStopEventon stop. - DiscManager: Now firesDiscRegisteredEventon disc creation andDiscRemovedEventon disc deletion.Technical
- New package:de.boondocksulfur.customjukebox.api.eventswith 4 event classes - All events follow standard Bukkit event patterns (HandlerList, static getHandlerList) - Zero behavior change for existing users — events are no-ops without listeners - Foundation for the new [BS-CustomJukebox Bedrock Extension](https://modrinth.com/plugin/bs-customjukebox-bedrock-exte…2.2.1BS CustomJukebox 2.2.1May 4, 2026 [2.2.1] - 2026-05-03
Fixed
- UpdateChecker: Now filters by game version via Modrinth API so users only see updates compatible with their Minecraft version. Prevents cross-version update notifications (e.g., 26.1 updates shown to 1.21.x servers).2.2.0BS CustomJukebox 2.2.0May 2, 2026 [2.2.0] - 2026-05-02
Added
- Public API Events: New event system for companion plugins -DiscPlaybackStartEvent— Cancellable event fired when a disc starts playing. Exposes disc, location, and mutable listener set. -DiscPlaybackStopEvent— Fired when playback stops, withStopReasonenum (MANUAL, DURATION_END, BLOCK_BREAK, PLUGIN). -DiscRegisteredEvent— Fired when a new disc is created via GUI or config. -DiscRemovedEvent— Fired when a disc is removed, includes a snapshot of the deleted disc. - API method:CustomJukeboxAPI.getPluginDataFolder()— Allows companion plugins to locate disc sound files.Changed
- PlaybackManager: Now firesDiscPlaybackStartEventbefore playing sounds (allows cancellation and listener modification) andDiscPlaybackStopEventon stop. - DiscManager: Now firesDiscRegisteredEventon disc creation andDiscRemovedEventon disc deletion.Technical
- New package:de.boondocksulfur.customjukebox.api.eventswith 4 event classes - All events follow standard Bukkit event patterns (HandlerList, static getHandlerList) - Zero behavior change for existing users — events are no-ops without listeners - Foundation for the new [BS-CustomJukebox Bedrock Extension](https://modrinth.com/plugin/bs-customjukebox-bedrock-exte…2.1.6BS CustomJukebox 2.1.6May 1, 2026 [2.1.6] - 2026-05-01
Fixed
- Critical: sound/soundKey field mismatch — Discs created or edited via GUI wrote"soundKey"to disc.json, but the loader only read"sound". After a reload, the custom sound was silently lost. -saveDiscToConfig()andupdateDiscField()now consistently write"sound"(the official field name) -parseDiscFromJson()now reads"sound"with"soundKey"as backward-compatible fallback - DiscEditorGUIv2 now passes"sound"instead of"soundKey"toupdateDiscField()- Existing disc.json files with"soundKey"entries will be read correctly (no manual migration needed) - ParrotDanceListener NPE: Added null-check forgetWorld()before callinggetNearbyEntities(). Prevents crash when jukebox is in an unloaded world. - JukeboxPlayback thread-safety: Changed internallistenersset fromHashSettoConcurrentHashMap.newKeySet(). Prevents potentialConcurrentModificationExceptionwhen players join/leave during playback. - Config values without bounds validation: All numeric config getters now clamp to valid ranges: -volume: 0.0–4.0 -creeper-drop-chance/loot-chance: 0.0–1.0 -max-loot-discs/fragments-per-disc: 1–64 -jukebox-hearing-radius: 1–512 -dance-radius: 1–32Removed
- ColorUtil class deleted: Deprecated since v2.1.0, internally fully replaced byAdventureUtil. No remaining usages in plugin code. Removed unused import fromDiscEditorGUIv2.Changed
- README overhauled: Resource Pack documentation - Replaced misleadingpack_format: 34for "Minecraft 1.21.x" with accurate per-version format table - Added modernmin_format/max_formatexamples for Minecraft 1.21.9, 1.21.10, and 1.21.11 - Added GitHub URL warning (don't use/blob/URLs for server resource packs) - Added ZIP structure documentation (correct vs incorrect root layout) - Added troubleshooting checklist for "Resource Pack hash is outdated" error - Example resource pack updated:pack.mcmetanow usesmin_format: [69, 0]/max_format: [75, 0](compatible with MC 1.21.9–1.21.11) - Example resource pack README fixed: - Added note that template does not include real.oggfiles - Replaced outdatedsupported_formatsreference withmin_format/max_formatexplanation - Unified sound key examples to consistently usemusic_disc.prefix - Fixed incorrectconfig.ymlreference →server.propertiesasresource-pack-sha12.1.5BS CustomJukebox 2.1.5Apr 18, 2026 [2.1.5] - 2026-04-18
Fixed
- Permission system completely overhauled: Players were incorrectly blocked in areas without explicit WorldGuard flags -customjukebox.useis now actually checked (previously only defined but never used) - WorldGuard now only checks for explicituse deny- Areas without the flag allow jukeboxes - Specific error messages instead of generic “no-permission” (Region/Claim/Permission separated) - New permissioncustomjukebox.bypass.protectionto bypass WorldGuard/GriefPrevention (default: OP) - Various bug fixes: Fixed several potential crashes and race conditions - Thread safety for the playlist queue (synchronized methods) - Safer file saving withFiles.move()instead of delete+rename (prevents data loss on Windows) - Null checks for metadata access, WorldGuard locations, and Adventure API colors - ArrayIndexOutOfBounds protection in the Disc Editor for corrupt states - UpdateChecker: JSON null safety and resource leak fix - Minor improvements: - Mute state is now persisted in config.json (survives server restart) - Location-based HashMap key replaced with string key (more reliable cooldown) - Tab completion now shows subcommands even with empty input - Category validation in the Creation Wizard (warning for non-existent categories) - More efficient item distribution (a stack instead of a loop) - Plugin tasks are now properly terminated on onDisableChanged
- Paper API 1.21.11: Plugin now compiles and runs against Paper 1.21.11 - Resource Pack updated:pack_formatset to 75 (1.21.11), sound namespace corrected - Default Configs:versionfield added to config.json and disc.json - README: Detailed permissions documentation with tables and descriptionsAdded
- Permissioncustomjukebox.bypass.protection(default: OP, included incustomjukebox.admin) - New error messages in all 4 languages:no-permission-jukebox,no-permission-region,no-permission-claim2.1.4BS CustomJukebox 2.1.4Apr 14, 2026 [2.1.4] - 2026-04-14
Fixed
- False update notification: Fixed plugin incorrectly showing "Update to 2.1.3 available" despite already running 2.1.3 - Gradle'sprocessResourcesdid not track the project version as an explicit task input - Addedinputs.property("version", project.version)to ensure version changes always trigger resource re-processing2.1.3BS CustomJukebox 2.1.3Apr 11, 2026 [2.1.3] - 2026-04-11
Fixed
- Message formatting: All chat messages now use MessageUtil with Adventure API - Replaced all rawsender.sendMessage(String)/player.sendMessage(String)calls - Replaced hardcoded section sign color codes with ampersand codes - Affects all commands, listeners, and GUI components - Error handling: Replaced allprintStackTrace()calls with properLogger.log()usage - CJBCommand, ConfigManager, DiscManager, IntegrationManager - Give/Fragment command bug: Fixed commands giving items even with invalid amount input - Added missingreturnafter NumberFormatException in GiveSubcommand and FragmentSubcommand - Vanilla sound overlap: Fixed volume fluctuations during custom disc playback - Addedjukebox.stopPlaying()to stop server-side vanilla playback - Prevents Jukebox block entity from periodically re-triggering vanilla sound - Applied to both manual disc insertion and GUI-based insertion2.1.2BS CustomJukebox 2.1.2Mar 29, 2026 [2.1.2] - 2026-03-29
Fixed
- Message formatting: Fixed color codes showing as garbled text on Paper 1.21+ servers - Critical: Wrong disc playing after quick switch: Added comprehensive fix for race conditions - Implemented 500ms cooldown between disc changes to prevent race conditions - Added triple-verification system to ensure correct disc identification - Re-identify disc after insertion to catch quick swaps - Stop any existing playback immediately on new disc insertion - Added final verification before playback starts - Critical: Playlist skip race condition: Fixed tracks being skipped in playlists - AddedpeekNext()method for safe preview without index advancement - Eliminated race conditions in playlist progression logic - Ensured thread-safe playlist queue operations - Critical: Data loss on disc save: Implemented atomic file operations - Write to temporary file first, then atomic rename - Automatic backup restoration on save failure - AddedgetLatestBackup()recovery mechanism - Prevents disc.json corruption on write failures - Memory leak with player UUIDs: Fixed players remaining in listener lists - AddedPlayerQuitEventhandler to clean up UUIDs - ImplementedremovePlayerFromAllPlaybacks()method - Prevents memory accumulation over time - HTML entities in display texts: Fixed & showing instead of color codes - AddedunescapeHtmlEntities()method in DiscManager - Properly decodes HTML entities when loading from JSON - Backup decoder in JukeboxListener for compatibility - Vanilla sound stop mechanism: Improved reliability - Increased attempts from 2 to 4 (at 1, 5, 10, 20 ticks) - Optimized performance with squared distance calculations - Added chunk-based pre-filtering for efficiency - Folia support issues: Fixed fallback problems - Better error messages instead of silent fallback - Improved API change detection - Warns admins about compatibility issues - Mute state not persistent: Now saves across reloads - AddedloadMuteState()andsaveMuteState()methods - Mute state stored in config.json - Survives plugin reloads and server restartsSecurity
- Thread-safety improvements: Migrated to ConcurrentHashMap - All GUI classes now use thread-safe collections - Prevents ConcurrentModificationException - Better multi-threaded performance - Permission checks in GUIs: Added runtime permission validation - GUI handlers now verify permissions on every click - Prevents exploitation when permissions change during use - Immediate closure if permissions are revokedPerformance
- Location cloning optimization: Reduced unnecessary object creation - AddedgetJukeboxLocationClone()for explicit cloning - Internal methods use reference for performance - Documented when cloning is necessary - Input validation: Added comprehensive parameter checking - CustomDisc constructor validates all inputs - Throws IllegalArgumentException for invalid values - Prevents creation of invalid disc objectsTechnical
- Fixed missing imports in JukeboxListener - Updated all GUI classes for thread-safety - Enhanced debug logging for troubleshooting - Improved error recovery mechanisms2.1.1BS CustomJukebox 2.1.1Feb 21, 2026 2.1.0BS CustomJukebox 2.1.0Feb 18, 2026 [2.1.0] - 2026-02-18
Added
- Adventure API Integration: Migrated to modern Paper Adventure API - NewAdventureUtilclass for unified text component handling - Full support for HEX colors, gradients, and MiniMessage format - Better performance and future-proofing for Paper 1.21+Changed
- Modernized Text Handling: Core components now use Adventure API -CustomDisc.createItemStack()usesdisplayName()andlore()methods -DiscFragment.createItemStack()uses Adventure Components -JukeboxListenertitles and action bars use Adventure API - Player.sendTitle() → Title.title() with proper durations - Player.sendActionBar() → Adventure Component-basedFixed
- Critical Playlist Bug: Fixed playlists stopping after first song -stopPlayback()now hasclearPlaylistQueueparameter - Playlist queue is preserved during auto-progression to next track - Playlist queue is cleared only when manually stopping playback - This was a critical bug preventing playlists from working correctly! - Resource Leak in UpdateChecker: Properly closes HTTP connections - Added try-finally blocks with explicit connection.disconnect() - Added proper BufferedReader closing - Prevents resource exhaustion on update checksDeprecated
- ColorUtil class marked as @Deprecated (but still functional) - Kept for backwards compatibility - New code should useAdventureUtilinstead - Legacy ChatColor/BungeeCord API calls will be phased outTechnical
- Deprecation Warning Reduction: 70 → 1 warning (98.6% reduction) - Migrated all ColorUtil.colorize() calls to AdventureUtil - Replaced 7 internal deprecated method calls - Only remaining warning: GriefPrevention external API (cannot be fixed) - Adventure API bundled in Paper 1.21+ (no extra dependency needed) - Full backwards compatibility maintained - All existing features continue to work unchangedMigration Notes
- Plugin users: No action required - update is fully compatible - Plugin developers using API: Consider migrating to AdventureUtil for new code - All color codes (&a, &#RRGGBB, gradients) continue to work as before2.0.0BS CustomJukebox 2.0.0Jan 6, 2026 [2.0.0] - 2026-01-06
Added
- Folia Support: Full compatibility with Folia (region-threaded) servers - Addedfolia-supported: trueflag in plugin.yml - NewSchedulerUtilclass for cross-platform scheduler abstraction - Automatic detection of Folia vs Paper/Spigot at runtime - Uses reflection to call Folia API without compile-time dependency - Region scheduler for location-based tasks - Entity scheduler for player/entity-specific tasks - Async scheduler for background operations - All 26 scheduler calls migrated to use SchedulerUtilFixed
- Folia Scheduler Bug: Fixed UnsupportedOperationException when running on Folia servers - Corrected all reflection API calls to use proper Folia methods -runLater()now usesBukkit.getRegionScheduler().runDelayed()-run()now usesBukkit.getRegionScheduler().run()-runAsync()now usesBukkit.getAsyncScheduler().runNow()-runAsyncLater()now usesBukkit.getAsyncScheduler().runDelayed()- Sound Key Validation: Removed strict validation that rejected valid sound keys - Now accepts bothnamespace:keyformat (e.g.,customjukebox:epic_journey) - AND legacymusic_disc.nameformat (e.g.,music_disc.traeumer) - Validation errors for 18 discs resolved - ConfigManager NullPointerException: Fixed initialization crash - RemovedisDebug()check increateBackup()method during initialization - Plugin now starts without errors - PlaybackManager NullPointerException: Fixed task storage crash on Folia - Added null checks before storing tasks in ConcurrentHashMap - Folia tasks return null (expected behavior) - now handled gracefully - Fixed in bothscheduleAutoStop()andscheduleLoopTask()methodsTechnical
- NewSchedulerUtilclass with Folia detection viaio.papermc.paper.threadedregions.RegionizedServer- Uses Java reflection to avoid compile-time Folia dependency - Fallback to Paper scheduler if reflection fails - All scheduler methods return nullableBukkitTask(null on Folia) - Enhanced error logging for scheduler failures - Full backwards compatibility with Paper/Spigot serversMigration Notes
- Plugin now works on both Folia AND Paper/Spigot servers - No configuration changes required - Automatic server type detection - Zero performance impact on Paper/Spigot servers ---1.3.0BS CustomJukebox 1.3.0Dec 31, 2025 [1.3.0] - 2025-12-31
Added
- Public API for Plugin Developers: NewCustomJukeboxAPIclass allows other plugins to interact with CustomJukebox - Access to all discs, fragments, categories, and playlists - Playback control methods - Configuration access - Integration checks (WorldGuard, GriefPrevention) - Full JavaDoc documentation - Disc Categories System: Organize discs by theme or genre - Define categories indisc.jsonwith display name and description - Assign discs to categories using"category"field - Filter discs by category via API - Example categories: Ambient, Epic, Nature - Playlist System: Group discs for sequential playback with automatic queue management - Create playlists indisc.jsonwith list of disc IDs OR in-game with commands/GUI - Commands:/cjb playlist list|info|play|create|delete|add|remove|rename|editfor full control - In-Game Management: Create and edit playlists without touching config files - GUI Editor: Visual playlist editor with click-to-add/remove interface - Integrated into Admin GUI for centralized management - Automatic progression: Plays next disc when current finishes - Loop support: Endless playlist playback with/cjb playlist play <name> loop- Queue management: Tracks current position and handles transitions - Auto-save: All changes instantly saved todisc.json- Perfect for events, ambient music, or themed collections - Admin GUI System: Comprehensive in-game administration interface - Main Admin Panel: Accessible via/cjb gui(Admin button at bottom for OPs) - Disc Creation Wizard: 7-step chat wizard for creating new discs - Step-by-step guidance through all fields (ID, name, author, sound, duration, category, model data) - Input validation at each step (ID format, sound key syntax, numeric values) - Shows existing categories during creation - Summary preview before final creation - Auto-save todisc.json- Disc Editor: Hybrid GUI/Chat system for editing existing discs - GUI Selectors for numeric values: - Duration selector with presets (30s, 60s, 90s... up to 600s) + custom input - Custom Model Data selector (1-20) + custom input - Category selector showing all categories + create new option - Chat Input for text fields (Display Name, Author, Sound Key) - All changes auto-save immediately - Delete confirmation dialog for safety - Playlist Management: Full playlist CRUD operations via GUI - Create new playlists (chat-based for now) - Edit playlists with visual disc selector (click to add/remove) - Delete playlists with confirmation - Live status indicators (In playlist) - Category Management: Organize discs by categories - Category Creation Wizard: 3-step chat wizard for creating categories - ID input with validation (lowercase, no spaces) - Display Name with full color support (legacy, HEX, gradients) - Optional description field - Summary confirmation before creation - Category Editor GUI: Visual editor for existing categories - Edit display name with advanced color support - Edit description with color codes - Live preview of changes - Auto-save to
disc.json- Create and delete categories - View disc count per category - Easy category assignment via selector in disc editor - No more manual JSON editing for most operations! - Advanced Color System: Full support for modern Minecraft color codes - HEX Colors: Use&#RRGGBBor#RRGGBBformat (e.g.,&#FF5555for red) - Gradient Support: Create color gradients with<gradient:#START:#END>text</gradient>- Example:<gradient:#FF0000:#0000FF>Epic Soundtrack</gradient>creates red-to-blue gradient - Automatically interpolates colors across each character - Legacy Codes: Still supports standard codes (&a,&b,&c, etc.) - Formatting: Bold (&l), italic (&o), underline (&n), strikethrough (&m) - Works Everywhere: Display names, authors, descriptions, categories, lore - NewColorUtilclass handles all color processing - Better user guidance in all wizards and editors - bStats Metrics Integration: Anonymous plugin statistics - Track plugin usage and feature adoption - Custom charts for language, integrations, and feature usage - Helps improve plugin development - Fully privacy-respecting (configurable via bStats) - PlaceholderAPI Support: 15+ placeholders for use in other plugins -%customjukebox_version%- Plugin version -%customjukebox_total_discs%- Total number of custom discs -%customjukebox_hand_disc_name%- Name of disc in main hand -%customjukebox_hand_disc_author%- Author of disc in hand -%customjukebox_volume%- Current playback volume - And many more! See API documentation for full list - Configurable Jukebox Hearing Radius: New config optionplayback.jukebox-hearing-radius- Default: 64 blocks - Controls how far players can see disc title/actionbar when disc is inserted - Separate from sound playback radius (controlled by volume)Changed
- Improved Tab-Completion: Commands now suggest disc display names in addition to IDs - Works for/cjb give,/cjb info,/cjb play,/cjb fragment- Automatically strips color codes for better matching - More user-friendly for admins - Enhanced CustomDisc Model: Added category field support - Discs can now be assigned to categories - Backwards compatible (category is optional) - Updated Dependencies: - Added bStats 3.1.0 - Added PlaceholderAPI 2.11.6 (soft-dependency)Fixed
- Color Codes in Author Field: Author field now properly supports color codes - Previously, color codes in author field were not processed - Now supports legacy codes (&a-&f), HEX colors (&#FF5555), and gradients - Resolves user report about non-working color codes in author field - Update Checker Version Comparison: Fixed false "update available" notifications - Previously used string comparison instead of semantic versioning - Would incorrectly show "1.0.1" as newer than "1.3.0" - Now properly compares versions numerically (1.3.0 > 1.0.1) - Added support for development versions (shows "development version" message) - Handles version suffixes like "-SNAPSHOT" correctly - Category Management TODOs: Completed all category management features - Category creation wizard now fully implemented (previously TODO) - Category editor GUI now fully functional (previously TODO) - All category operations work seamlessly through Admin GUITechnical
- New model classes:DiscCategory,DiscPlaylist- Extended DiscManager with full CRUD methods for discs, playlists, and categories - Added PlaybackManager queue system for automatic disc progression - New command:PlaylistSubcommandwith 9 actions (list/info/play/create/delete/add/remove/rename/edit) - New GUIs: -AdminGUI- Main admin panel with navigation to all management functions -DiscCreationWizard- 7-step chat wizard for disc creation with validation -DiscEditorGUIv2- Hybrid GUI/Chat editor with selector menus - Duration selector with preset values - Custom Model Data selector (1-20) - Category selector with create option -PlaylistEditorGUI- Visual playlist editor with click-to-add/remove interface -CategoryCreationWizard- 3-step chat wizard for category creation -CategoryEditorGUI- Visual category editor with chat input for text fields - ExtendedGuiSubcommandwith admin button integration - New Utilities: -ColorUtil- Advanced color processing with HEX and gradient support - Replaces basicChatColor.translateAlternateColorCodes()throughout plugin - Supports legacy codes, HEX colors, and gradients - Used by all managers and GUIs for consistent1.2.4BS CustomJukebox 1.2.4Dec 23, 2025 [1.2.4] - 2025-12-23
Fixed
- Documentation: Correctedsounds.jsonformat in README and example resource pack - Sound event keys now use proper format:music_disc.<disc_id>(e.g.,music_disc.epic_journey) - Sound file paths now use relative paths without namespace (e.g.,custom/music/epic_journey) - Updated all example configurations to match working server format - Removed unnecessary subtitle fields from examples - Example Configuration: Updated defaultdisc.jsonwith correct sound key format - Changed fromcustomjukebox:*tominecraft:music_disc.*format - All three example discs now use consistent, working configuration - Matches the format validated on production serversChanged
- Resource Pack Documentation: Improved clarity in sounds.json setup instructions - Added clear explanation of sound event key format - Documented correct file path structure for .ogg files - Updated Important Notes section with accurate format information1.2.3BS CustomJukebox 1.2.3Dec 18, 2025 [1.2.3] - 2025-12-15
Fixed
- Critical Loop-Task Bug: Fixed issue where music would spontaneously restart - Loop tasks were not properly canceled before creating new playback sessions - Multiple tasks could run simultaneously, causing unexpected music restarts - Now properly cancels old tasks BEFORE removing playback and starting new loop - Prevents task accumulation that led to random music playback - Added proper cleanup sequence: cancel task → stop sound → remove playback → start new - Play Command Parameter Order: Fixed/cjb playcommand parameter parsing issues - Parameters can now be provided in any order (e.g.,/cjb play disc loop 100or/cjb play disc 100 loop) - Previously required specific order (loop had to come before range) - Added duplicate parameter detection with debug logging - Improved error messages for invalid parameters with helpful suggestions - Enhanced tab-completion to only suggest unused parametersTechnical
- Improved task cancellation logic inscheduleLoop()method - Better cleanup sequence prevents orphaned tasks - Enhanced debugging output for loop operations - Refactored PlaySubcommand parameter parsing with order-independent logic - Addedplayback-invalid-parameterlanguage key to all 4 language files1.2.2BS CustomJukebox 1.2.2Dec 15, 2025 [1.2.2] - 2025-12-15
Added
- Mute/Unmute Commands: New commands for quickly silencing and restoring playback -/cjb mute [restart]- Mutes all playback by setting volume to 0 -/cjb unmute [restart]- Restores previous volume before muting - Saves volume state before muting for seamless restoration - Optional restart parameter to apply changes to active playbacks immediately - Volume Presets: Quick volume adjustment with preset names -silent/mute/off→ 0.0 -quiet/low/soft→ 0.5 -normal/default/medium→ 1.0 -loud/high→ 2.0 -max/maximum/full→ 4.0 - Example:/cjb volume quietor/cjb volume loud restartChanged
- Improved Volume Control: Enhanced volume adjustment system - Finer granularity: 41 volume levels (0.0 to 4.0 in 0.1 increments) - Enhanced tab-completion with all numeric values and preset names - Better precision display with 2 decimal places (e.g., 1.50) - Improved error messages for invalid volume valuesTechnical
- Added mute state tracking in ConfigManager - Volume presets support multiple aliases for user convenience - Enhanced tab-completion system for better user experience - All new features fully translated in 4 languages (EN, DE, ES, IT)1.2.1BS CustomJukebox 1.2.1Dec 14, 2025 [1.2.1] - 2025-12-14
Fixed
- Critical Configuration Fix: Fixed inconsistency betweendisc.jsonandsounds.jsondefault configurations - Updated example disc entries to use correct sound keys (customjukebox:epic_journey, etc.) - Now includes three example discs: Epic Journey, Ocean Dreams, and Forest Walk - All sound keys now properly match between disc.json and sounds.jsonAdded
- Startup Validation System: Plugin now validates all disc configurations on startup - Checks for missing or invalid sound keys - Verifies sound key format (namespace:sound_name) - Warns about missing duration settings - Provides clear error messages for configuration issues - Helps identify why sounds might not play - Enhanced Error Handling: Significantly improved error feedback when sounds fail to play - Detailed console logs with troubleshooting steps - In-game notifications to players when sound playback fails - Clear explanations of possible causes (missing resource pack, wrong sound key, etc.) - Suggestions for how to fix common issuesChanged
- Documentation Update: Completely updated resource pack README.md - All YAML references replaced with JSON (disc.json, config.json) - Corrected configuration examples to use JSON syntax - Updated command examples and troubleshooting guides - Added information about server.properties resource pack configuration - More detailed testing and debugging instructionsTechnical
- AddedvalidateDiscs()method in DiscManager for configuration validation - EnhancedplaySound()method in PlaybackManager with comprehensive error reporting - Improved logging output for debugging sound playback issues - Better player feedback when sound playback fails1.2.0BS CustomJukebox 1.2.0Dec 14, 2025 [1.2.0] - 2025-12-13
Added
- Playback Range System: Control who hears custom music with range parameters -/cjb play <disc> [loop] [global|world|<radius>]- global: All players on the server hear the music - world: Only players in the same world - Custom radius: Specify exact block radius (e.g.,50,100,200) - Perfect for server-wide events, world-specific ambiance, or localized music zones - Volume Restart Feature:/cjb volume <value> restart- Apply volume changes to already playing songs instantly - Automatically restarts all active playbacks with new volume - No need to manually stop and restart songs anymore - PlaybackRange Model: New enum system for managing playback ranges - Clean API for future range-based features - Supports NORMAL, GLOBAL, WORLD, and CUSTOM_RADIUS types - Automatic parsing from command parametersChanged
- Extended PlaybackManager with range-aware sound distribution - Enhanced JukeboxPlayback model to track playback range - Loop functionality now preserves range settings across restarts - Updated all command usages to include new parametersAdded (Features)
- Smart player detection based on range type - Efficient range checking for different playback scopes - Range information displayed in playback success messagesUpdated (Translations)
- All 4 languages updated with new range-related messages (DE, EN, ES, IT) - New messages:playback-range-info,playback-invalid-range,volume-restarted- Updated command usage strings for all languagesTechnical
- NewPlaybackRangeclass for type-safe range management - AddedrestartAllPlaybacks()method to PlaybackManager - ExtendedshouldPlayerHearPlayback()with range logic - Improved playback session management1.1.0BS CustomJukebox 1.1.0Dec 13, 2025 [1.1.0] - 2025-12-13
Added
- Direct Playback Command: New/cjb play <disc> [loop]command allows OPs to play custom discs directly at their location - Supports optionalloopparameter to enable infinite playback - No need to place physical jukeboxes anymore - Perfect for events and server-wide music - Stop Command: New/cjb stopcommand to stop all active playbacks - Instantly stops all looping and non-looping sounds - Useful for ending events or silencing the server - Volume Control: New/cjb volume <0.0-4.0>command for centralized volume management - Adjusts playback volume globally - Range: 0.0 (silent) to 4.0 (maximum) - Persists in config.json - Without arguments, displays current volume - Loop Functionality: Songs can now be played in an infinite loop - Automatically restarts when the song ends - Configurable via command parameter - Perfect for background music during events - Playback Configuration: Newplaybacksection in config.json -volume: Global playback volume (default: 4.0) -default-loop: Default loop behavior (default: false)Changed
- Updated PlaybackManager to support dynamic volume control - Extended JukeboxPlayback model with loop flag tracking - Volume is now read from config instead of hardcoded constant - PlaybackManager now schedules loop tasks instead of just stop tasksAdded (Permissions)
-customjukebox.play- Allows playing discs directly (default: op) -customjukebox.stop- Allows stopping all playbacks (default: op) -customjukebox.volume- Allows changing volume (default: op)Added (Translations)
- Added German translations for all new commands and messages - Added English translations for all new commands and messages - Added Spanish translations for all new commands and messages - Added Italian translations for all new commands and messagesUpdated (Documentation)
- Updated README.md with new commands and features - Updated plugin.yml command usage - Version bumped to 1.1.01.0.0BS CustomJukebox 1.0.0Dec 8, 2025
Similar projects
Plugin →VeinMiner
Mine the whole vein on mining a single ore/block. Make the tedious mining experience to something satisfying and fun! FTB Ultimine alternative
99.3MSueta
VeinMiner Enchantment
Veinminer Addon - Adds vineminer enchantment to enchanting tables. Only tools with the enchantment can veinmine
18MSueta
Emotecraft
Create your own emotes in Minecraft.
7.5MSueta
Customizable Player Models
Customize your minecraft avatar!
3.2MSueta
ItemSwapper
Inventory update concept for hotswapping items.
2.1MSueta
TAB
An all-in-one solution that works
1.3MSueta