Everything you'll ever need to enhance and/or restrict commands on your server.
4.0.0 – 2026-04-18
This is a complete rewrite of the plugin. Player state lives in a database instead of a YAML file, commands have been regrouped into nested subcommands, and a long list of new features landed. Legacy config.yml works unchanged and every pre-4.0 command name is still routable as an alias, so upgrades are drop-in for server admins. Plugins consuming the Java API need to update their imports – see Breaking below.
⚠️ Breaking
- Java package renamed from
cz.boosik.boosCooldown→software.boos.boosCooldown. Plugins that depend onBoosCooldownAPIor the custom events must update their imports and addloadbefore: [boosCooldowns]to theirplugin.yml. - Minimum Java version raised from 8 to 21.
- Maven groupId changed from
cz.boosiktosoftware.boos.
✨ Added
Persistence
- Database-backed state – SQLite (default, zero-config) or MySQL / MariaDB for networks.
- Schema-versioned migrations (V1 initial, V2 user_preferences, V3 audit_log, V4 config_version).
- HikariCP connection pool with leak detection.
- Auto-migration of legacy
users.ymlon first start (old file renamed tousers.yml.migrated-<timestamp>). - JDBC drivers auto-downloaded via
libraries:inplugin.yml.
Multi-server
- Cooldowns, limits, server cooldowns, user preferences and scheduled resets shared across every server pointing at the same MySQL/MariaDB.
- Server-wide cooldowns (
server_cooldown:) – one player using a command blocks everyone else on the network for the window. - Config drift detection – each node hashes
config.ymlon enable and on/bcd reload, a periodic monitor logs a warning when peers disagree,/bcd diffreports which nodes differ. options.options.node_idfor human-readable node labels.
Per-command rules
- Progressive cooldowns via
cooldown_multiplierandcooldown_reset_after. - Per-world restrictions (
worlds: [survival, nether]). - WorldGuard regions (
regions: [spawn, arena]) as soft-depend. - Group inheritance via
_inherits: defaultso VIP groups only override what changes. - Disable commands via
disabled: truewithout unregistering them. - Per-command messages (
cooldown_message,warmup_message,disabled_message,server_cooldown_message) with per-player PlaceholderAPI expansion.
Player UX
- Boss bar progress indicator during warmup.
- Action bar for warmup countdown and cooldown notices on attempt.
- Warmup sounds (
warmup_sound,complete_sound) and particles (warmup_particle) per command. - Confirmation dialogs – clickable
[Yes]/[No]for commands with a price/limit, per-player toggle persisted in DB. - Refund on warmup cancel (
refund_on_warmup_cancel) – returns money, items and XP when a warmup is aborted. - Localization – drop a
messages_<locale>.ymland messages follow the client language. Bundled example:messages_cs.yml.
Admin tooling
- Commands regrouped under
/bcd clear,/bcd rule,/bcd grant,/bcd resetgroups. - New subcommands:
status,check,clear all,rule get,grant uses,tempset,validate,audit,diff,help. - Autogenerated
/bcd help– permission-filtered, grouped into Player / Administration / Diagnostics sections. - Smart tab completion – suggests option keys, online players, configured commands at every level.
/bcd validate– config linter catches unknown option keys, invalid durations, typos in materials and sounds./bcd tempset– option override that auto-restores after a duration.- Legacy aliases – every pre-4.0 command name (
clearcooldowns,set,info,scheduleglobalreset, …) still routes to its new home.
Automation
- Event-based cooldown resets via
event_triggers:– clear a player's cooldown when they kill a specific entity or earn an advancement, with optional chat message, sound cue and server-wide broadcast. - Scheduled global limit resets via
/bcd reset schedule <cmd> <time>, visible through/bcd reset list, persisted in DB. - Namespace-aware command handling (
apply_rules_to_prefixed_syntax: true) – rewrites/minecraft:tp→/tpso plugin rules still apply, without needing the hard syntax blocker.
Integrations
- PlaceholderAPI expansion registered automatically:
%boos_remaining_<cmd>%,%boos_remaining_seconds_<cmd>%,%boos_on_cooldown_<cmd>%,%boos_server_cooldown_<cmd>%,%boos_uses_<cmd>%,%boos_uses_remaining_<cmd>%. - Foreign placeholders inside plugin messages – any
%vault_eco_balance%/%luckperms_primary_group%etc. resolves per-player in cooldown/warmup/disabled messages. - Vault, PlayerPoints, WorldGuard, LuckPerms detected at runtime; missing integration disables its feature, never breaks startup.
- bStats – 13 custom charts covering storage backend (with driver version drill-down), feature toggles, detected integrations, multi-node setup, locale distribution, config scale, warmup cancel sources.
Developer
- Public
BoosCooldownAPIfacade withisOnCooldown,setCooldown,getRemainingUses, etc. - Custom cancellable Bukkit events:
CooldownEvent,WarmupEvent,CommandEvent. - 142 tests – JUnit 5 + Mockito + MockBukkit integration tests; full CI workflow on every PR.
- JMH benchmark for the cooldown hot-path.
- GitHub Actions CI workflow (
.github/workflows/ci.yml).
Security
- All SQL uses parameterized
PreparedStatement. - Vault / PlayerPoints / PlaceholderAPI / WorldGuard class references isolated behind
isPluginEnabledchecks andLinkageErrorcatches – plugin boots cleanly even when every optional dependency is missing. - Command pipeline wrapped in try/catch so a bug in a single check can never block every command on the server.
🔧 Changed
- Vault / PlayerPoints no longer cause
NoClassDefFoundErroron servers that don't have them – integrations are now fully soft-depend-safe. - Package structure – monolithic
BoosCoolDownListener(434 lines) split into a service / listener / command / persistence layout. StaticManagersreplaced with an injectedServicescontainer. - Build target – Paper 1.21.8 API,
plugin.ymldeclaresapi-version: "1.20"so the jar runs on Paper 1.20+ through 26.1.2 without a rebuild. - Cooldown storage key – previously
String.hashCode()(collidable, opaque), now a normalized, stableCommandKeythat's human-readable during debugging. - Timestamps –
SimpleDateFormat("dd.MM.yyyy HH:mm:ss")replaced byjava.time.Instant+ epoch-millis columns. - Hot-path reads –
PlayerCommandPreprocessEventhandler only ever touches an in-memory cache; cache is pre-warmed onPlayerJoinEventso no cache miss can hit the DB synchronously. - Command pipeline ordering – every check now runs before mutations, preventing partial charges when a later gate rejects the command (see Fixed below).
- Bundled dependencies – HikariCP and bStats are shaded and relocated under
software.boos.boosCooldown.shaded.*.
🐛 Fixed
limit_reset_delayno longer sticks at zero – previously, once a player had consumed all their uses and the reset window elapsed, theresetAttimestamp was ignored and the limit stayed at 0 forever. The service now refreshes expired windows on read.- Pipeline no longer partially charges blocked commands – when a command is blocked by insufficient funds or warmup already started, the usage counter and economy balance are no longer mutated before the rejection. Check-then-commit pattern with refund fallback.
/plugin:commandsyntax now triggers plugin rules instead of bypassing them, with the option to either reject (syntax_blocker_enabled: true) or transparently rewrite (apply_rules_to_prefixed_syntax: true).- Plugin disable no longer leaks resources –
HikariDataSource.close()is called, the async executor'sawaitTermination(5s)waits for pending DB writes,Bukkit.getScheduler().cancelTasks(this)cancels timers. Prevents SQLite file locks on Windows after/reload. - Action bar / boss bar effects properly cancelled when warmup is aborted.
Sign.getLine(int)replaced with modernSign.getSide(Side.FRONT).getLine(int)for 1.20+ sign compatibility.Bukkit.getOfflinePlayer(String)blocking I/O removed from subcommands –Bukkit.getPlayerExact(String)is used instead.- Command listener fails open – an exception inside the pipeline logs to console but leaves the event alone, so Bukkit still dispatches the command. A bug can't block every command server-wide anymore.
- Config
get("commands.groups.default./kit.limit")path handling – rewritten to traverse nestedConfigurationSections instead of string path lookup, fixing rules for commands with slashes in their key. Sound.valueOf(String)deprecation – wrapped inLinkageErrorcatch so future Paper builds that remove it will log a warning instead of crashing the effect.- HikariCP leak detection set to 10s to surface unclosed connections early.
🗑️ Removed
- Legacy
Managers/package (replaced byservice/with dependency injection). - Legacy
Listeners/package (split into purpose-specific files underlistener/). - Legacy
Runnables/duplicate. users.yml– auto-migrated into the database on first run; old file is renamed, not deleted, for safety.
📦 Upgrade notes
Drop the new jar in and start the server. On first run the plugin will:
- Create
plugins/boosCooldowns/cooldowns.db(SQLite) with V1–V4 schema applied. - Detect
users.ymlif present, migrate its contents into the DB, and rename the file tousers.yml.migrated-<epoch>. - Keep every rule from the existing
config.yml(the format is backward compatible – new keys default to backward-compatible values).
If you manage more than one server, point every instance at the same MySQL/MariaDB via the new database: section and set node_id per server.
Earlier versions of boosCooldowns are tracked in the git history.
Information
| Published on | April 18, 2026 |
|---|---|
| Downloads | 2 |