Skip to content

cloud-processors-cooldown#

Postprocessor that adds command cooldowns.

Installation#

<dependencies>
    <dependency>
        <groupId>org.incendo</groupId>
        <artifactId>cloud-processors-cooldown</artifactId>
        <version>1.0.0-beta.1</version>
    </dependency>
</dependencies>
implementation("org.incendo:cloud-processors-cooldown:1.0.0-beta.1")
implementation 'org.incendo:cloud-processors-cooldown:1.0.0-beta.1'

Usage#

The cooldown system is managed by a CooldownManager, so the first step is to create an instance of that:

CooldownManager<YourSenderType> cooldownManager = CooldownManager.of(
  configuration
);

The configuration is an instance of CooldownConfiguration. Refer to the JavaDocs for information about specific options, but an example would be:

CooldownConfiguration.<YourSenderType>builder()
        .repository(CooldownRepository.forMap(new HashMap<>()))
        .addActiveCooldownListener(...)
        .addCooldownCreationListener(...)
        .cooldownNotifier(notifier)
        .build();

The listeners are invoked when different events take place. The active cooldown listener in particular may be used to inform the command sender that their command execution got blocked due to an active cooldown.

The repository stores active cooldowns for a command sender in the form of cooldown profiles. The cooldowns are grouped by their CooldownGroup, by default a unique group will be created per command. You may create a named group by using CooldownGroup.named(name). Commands that use the same cooldown group will have their cooldowns shared by the command sender.

You may create a repository from a map, CloudCache or even implement your own. If you want to persist the cooldowns across multiple temporary sessions then you may use a mapping repository to store the cooldown profiles for a persistent key, rather than the potentially temporary command sender objects:

CooldownRepository repository = CooldownRepository.mapping(
        sender -> sender.uuid(),
        CooldownRepository.forMap(new HashMap<UUID, CooldownProfile>())
);

You may also customize how the cooldown profiles are created by passing a CooldownProfileFactory to the CooldownConfiguration.

If you want to have the cooldowns automatically removed from the repository to prevent unused profiles from taking up memory you may register a ScheduledCleanupCreationListener:

CooldownRepository repository = CooldownRepository.forMap(new HashMap<>());
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
CooldownConfiguration configuration = CooldownConfiguration.<YourSenderType>builder()
        // ...
        .repository(repository)
        .addCreationListener(new ScheduledCleanupCreationListener(executorService, repository))
        .build();

You then need to register the postprocessor:

commandManager.registerCommandPostProcessor(
  cooldownManager.createPostprocessor()
);

Builders#

The cooldowns are configured using a Cooldown instance:

Cooldown cooldown = Cooldown.of(
  DurationFunction.constant(Duration.ofMinutes(5L))
);
Cooldown cooldown = Cooldown.of(
  DurationFunction.constant(Duration.ofMinutes(5L)),
  CooldownGroup.named("group-name")
);

which can then be applied to the command by either manually setting the meta value:

commandBuilder.meta(CooldownManager.META_COOLDOWN_DURATION, cooldown);

or by applying the cooldown to the builder:

commandBuilder.apply(cooldown);

Annotations#

Annotated commands may use the @Cooldown annotation:

@Cooldown(duration = 5, timeUnit = ChronoUnit.MINUTES, group = "some-group")
public void yourCommand() {
    // ...
}

You need to install the builder modifier for this to work:

CooldownBuilderModifier.install(annotationParser);