Cooldowns
CooldownManager<K> is a generic, thread-safe cooldown tracker. Each feature owns its own instance with a fixed duration, replacing scattered Map<UUID, Long> timestamp patterns.
Creating a cooldown
Section titled βCreating a cooldownβ// Per-feature cooldown, keyed by UUIDCooldownManager<UUID> healCooldown = new CooldownManager<>(30, TimeUnit.SECONDS);
// Can use any key typeCooldownManager<String> worldCooldown = new CooldownManager<>(5, TimeUnit.MINUTES);| Method | Description |
|---|---|
start(K key) |
Starts (or restarts) the cooldown for key |
isActive(K key) |
true if still cooling down |
remaining(K key) |
Milliseconds remaining, or 0 if not active |
reset(K key) |
Clears the cooldown for key |
clear() |
Clears all tracked cooldowns |
Usage pattern in a command
Section titled βUsage pattern in a commandβ@CommandMeta(name = "heal", playerOnly = true)public final class HealCommand extends CoreCommand {
private final CooldownManager<UUID> cooldown = new CooldownManager<>(30, TimeUnit.SECONDS);
@Override public void run(CommandContext context, Arguments args) throws CommandException { UUID uuid = context.player().getUniqueId();
if (cooldown.isActive(uuid)) { long remaining = cooldown.remaining(uuid); throw new CommandException("cooldown", Placeholder.of("time", TimeUtils.format(remaining))); }
// Do the heal Player player = context.player(); player.setHealth(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); cooldown.start(uuid); // start cooldown after use }}messages.yml:
cooldown: "<prefix><red>You must wait <yellow>%time% <red>before using this again."Thread safety
Section titled βThread safetyβCooldownManager uses a ConcurrentHashMap internally, so it is safe to call from both the main thread and async tasks.
Expired entries
Section titled βExpired entriesβEntries are lazily removed when isActive() or remaining() is called and the cooldown has expired. There is no background cleanup thread. For very long-lived servers with many unique keys, call clear() periodically if necessary.