Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ object Versions {
// tests
const val JUNIT_BOM = "5.13.4"
const val MOCKITO_CORE = "5.20.0"
const val ASSERTJ_CORE = "3.26.3"
const val AWAITILITY = "4.2.1"

}

This file was deleted.

2 changes: 2 additions & 0 deletions eternalcore-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ dependencies {
annotationProcessor("org.projectlombok:lombok:${Versions.LOMBOK}")

testImplementation("com.eternalcode:eternalcode-commons-bukkit:${Versions.ETERNALCODE_COMMONS}")
testImplementation("org.assertj:assertj-core:${Versions.ASSERTJ_CORE}")
testImplementation("org.awaitility:awaitility:${Versions.AWAITILITY}")
}

eternalShadow {
Expand Down
136 changes: 136 additions & 0 deletions eternalcore-core/src/main/java/com/eternalcode/core/delay/Delay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.eternalcode.core.delay;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.time.Duration;
import java.time.Instant;
import java.util.function.Supplier;

/**
* Provides per-entry delay management using Caffeine with wall-clock based expiration.
*
* @param <T> the key type
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wywal docsy

public class Delay<T> {

private static final long DEFAULT_MAXIMUM_SIZE = 50_000L;

private final Cache<T, Instant> cache;
private final Supplier<Duration> defaultDelay;

/**
* Creates a new delay with a default delay supplier and cache size limit.
*
* @param defaultDelay supplier providing default delay durations
* @param maximumSize maximum number of cached entries
*/
private Delay(Supplier<Duration> defaultDelay, long maximumSize) {
if (defaultDelay == null) {
throw new IllegalArgumentException("defaultDelay cannot be null");
}

if (maximumSize <= 0) {
throw new IllegalArgumentException("maximumSize must be > 0");
}

this.defaultDelay = defaultDelay;
this.cache = Caffeine.newBuilder()
.maximumSize(maximumSize)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

po co nam maximumSize?

.expireAfter(new InstantExpiry<T>())
.build();
}

/**
* Creates a new delay manager with the default maximum cache size.
*
* @param defaultDelay supplier providing default delay durations
*/
private Delay(Supplier<Duration> defaultDelay) {
this(defaultDelay, DEFAULT_MAXIMUM_SIZE);
}

/**
* Marks a delay for the given key using a specific duration.
*
* @param key the key to delay
* @param delay the duration of the delay
*/
public void markDelay(T key, Duration delay) {
if (delay.isZero() || delay.isNegative()) {
this.cache.invalidate(key);
}

this.cache.put(key, Instant.now().plus(delay));
}

/**
* Marks a delay for the given key using the default duration.
*
* @param key the key to delay
*/
public void markDelay(T key) {
this.markDelay(key, this.defaultDelay.get());
}

/**
* Removes any existing delay for the given key.
*
* @param key the key to clear
*/
public void unmarkDelay(T key) {
this.cache.invalidate(key);
}

/**
* Checks whether the given key currently has an active delay.
*
* @param key the key to check
* @return true if the delay is active, false otherwise
*/
public boolean hasDelay(T key) {
Instant delayExpireMoment = this.getExpireAt(key);
return Instant.now().isBefore(delayExpireMoment);
}

/**
* Returns the remaining delay duration for the given key.
*
* @param key the key to check
* @return the remaining duration, or {@code Duration.ZERO} if expired
*/
public Duration getRemaining(T key) {
return Duration.between(Instant.now(), this.getExpireAt(key));
}

/**
* Returns the expiration instant for the given key.
*
* @param key the key to check
* @return the expiration instant, or {@code Instant.MIN} if none
*/
private Instant getExpireAt(T key) {
return this.cache.asMap().getOrDefault(key, Instant.MIN);
}

/**
* Creates a new {@link Delay} instance with a default delay supplier.
*
* @param defaultDelay supplier providing default delay durations
* @return a new Delay instance
*/
public static <T> Delay<T> withDefault(Supplier<Duration> defaultDelay) {
return new Delay<>(defaultDelay);
}

/**
* Creates a new {@link Delay} instance with a default delay supplier and cache size.
*
* @param defaultDelay supplier providing default delay durations
* @param maximumSize maximum number of cached entries
* @return a new Delay instance
*/
public static <T> Delay<T> withDefault(Supplier<Duration> defaultDelay, long maximumSize) {
return new Delay<>(defaultDelay, maximumSize);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.eternalcode.core.delay;

import com.github.benmanes.caffeine.cache.Expiry;
import java.time.Duration;
import java.time.Instant;
import org.jetbrains.annotations.NotNull;

class InstantExpiry<T> implements Expiry<@NotNull T, @NotNull Instant> {

@Override
public long expireAfterCreate(@NotNull T key, @NotNull Instant expireTime, long currentTime) {
return timeToExpire(expireTime);
}

@Override
public long expireAfterUpdate(@NotNull T key, @NotNull Instant newExpireTime, long currentTime, long currentDuration) {
return timeToExpire(newExpireTime);
}

@Override
public long expireAfterRead(@NotNull T key, @NotNull Instant value, long currentTime, long currentDuration) {
return currentDuration;
}

private static long timeToExpire(Instant expireTime) {
Duration toExpire = Duration.between(Instant.now(), expireTime);
if (toExpire.isNegative()) {
return 0;
}

long nanos = toExpire.toNanos();
if (nanos == 0) {
return 1;
}

return nanos;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class AfkCommand {
this.noticeService = noticeService;
this.afkSettings = afkSettings;
this.afkService = afkService;
this.delay = new Delay<>(() -> this.afkSettings.afkCommandDelay());
this.delay = Delay.withDefault(() -> this.afkSettings.afkCommandDelay());
}

@Execute
Expand All @@ -51,7 +51,7 @@ void execute(@Sender Player player) {
}

if (this.delay.hasDelay(uuid)) {
Duration time = this.delay.getDurationToExpire(uuid);
Duration time = this.delay.getRemaining(uuid);

this.noticeService
.create()
Expand All @@ -64,6 +64,6 @@ void execute(@Sender Player player) {
}

this.afkService.switchAfk(uuid, AfkReason.COMMAND);
this.delay.markDelay(uuid, this.afkSettings.afkCommandDelay());
this.delay.markDelay(uuid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class HelpOpCommand {
this.helpOpSettings = helpOpSettings;
this.eventCaller = eventCaller;
this.server = server;
this.delay = new Delay<>(() -> this.helpOpSettings.helpOpDelay());
this.delay = Delay.withDefault(() -> this.helpOpSettings.helpOpDelay());
}

@Execute
Expand All @@ -58,7 +58,7 @@ void execute(@Sender Player player, @Join String message) {
}

if (this.delay.hasDelay(uuid)) {
Duration time = this.delay.getDurationToExpire(uuid);
Duration time = this.delay.getRemaining(uuid);

this.noticeService.create()
.notice(translation -> translation.helpOp().helpOpDelay())
Expand Down Expand Up @@ -91,7 +91,7 @@ void execute(@Sender Player player, @Join String message) {
.notice(translation -> translation.helpOp().send())
.send();

this.delay.markDelay(uuid, this.helpOpSettings.helpOpDelay());
this.delay.markDelay(uuid);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class RandomTeleportCommand {
this.randomTeleportService = randomTeleportService;
this.randomTeleportTaskService = randomTeleportTaskService;
this.randomTeleportSettings = randomTeleportSettings;
this.cooldown = new Delay<>(() -> this.randomTeleportSettings.cooldown());
this.cooldown = Delay.withDefault(() -> this.randomTeleportSettings.cooldown());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tutaj musi być provider () -> bo pobieramy wartość z configu a ona się reloaduje czasem

}

@Execute
Expand Down Expand Up @@ -68,7 +68,7 @@ void executeSelf(@Sender Player player) {
this.handleTeleportSuccess(player);
});

this.cooldown.markDelay(uuid, this.randomTeleportSettings.cooldown());
this.cooldown.markDelay(uuid);
}

@Execute
Expand Down Expand Up @@ -96,7 +96,7 @@ void executeOther(@Sender Viewer sender, @Arg Player player) {
this.handleAdminTeleport(sender, player);
});

this.cooldown.markDelay(uuid, this.randomTeleportSettings.cooldown());
this.cooldown.markDelay(uuid);
}

private void handleTeleportSuccess(Player player) {
Expand Down Expand Up @@ -129,7 +129,7 @@ private boolean hasRandomTeleportDelay(Player player) {
}

if (this.cooldown.hasDelay(uniqueId)) {
Duration time = this.cooldown.getDurationToExpire(uniqueId);
Duration time = this.cooldown.getRemaining(uniqueId);

this.noticeService.create()
.notice(translation -> translation.randomTeleport().randomTeleportDelay())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class RepairCommand {
RepairCommand(NoticeService noticeService, RepairSettings repairSettings) {
this.noticeService = noticeService;
this.repairSettings = repairSettings;
this.delay = new Delay<>(() -> this.repairSettings.repairDelay());
this.delay = Delay.withDefault(() -> this.repairSettings.repairDelay());
}

@Execute
Expand Down Expand Up @@ -73,7 +73,7 @@ void repair(@Sender Player player) {
.player(player.getUniqueId())
.send();

this.delay.markDelay(uuid, this.repairSettings.repairDelay());
this.delay.markDelay(uuid);
}

@Execute(name = "all")
Expand Down Expand Up @@ -117,7 +117,7 @@ void repairAll(@Sender Player player) {
.player(player.getUniqueId())
.send();

this.delay.markDelay(uuid, this.repairSettings.repairDelay());
this.delay.markDelay(uuid);
}

@Execute(name = "armor")
Expand Down Expand Up @@ -161,12 +161,12 @@ void repairArmor(@Sender Player player) {
.player(player.getUniqueId())
.send();

this.delay.markDelay(uuid, this.repairSettings.repairDelay());
this.delay.markDelay(uuid);
}

private boolean hasRepairDelay(UUID uuid) {
if (this.delay.hasDelay(uuid)) {
Duration time = this.delay.getDurationToExpire(uuid);
Duration time = this.delay.getRemaining(uuid);

this.noticeService
.create()
Expand Down
Loading