diff --git a/src/main/java/org/discordbots/api/client/DiscordBotListAPI.java b/src/main/java/org/discordbots/api/client/DiscordBotListAPI.java index 1dbd21c..19a5a1b 100644 --- a/src/main/java/org/discordbots/api/client/DiscordBotListAPI.java +++ b/src/main/java/org/discordbots/api/client/DiscordBotListAPI.java @@ -7,7 +7,16 @@ import java.util.Map; import java.util.concurrent.CompletionStage; +import org.apache.logging.log4j.util.BiConsumer; +import org.apache.logging.log4j.util.Supplier; + public interface DiscordBotListAPI { + void startAutoposter(int delayInSeconds, Supplier statsCallback, BiConsumer postCallback); + void startAutoposter(int delayInSeconds, Supplier statsCallback); + void startAutoposter(Supplier statsCallback, BiConsumer postCallback); + void startAutoposter(Supplier statsCallback); + + void stopAutoposter(); CompletionStage setStats(int shardId, int shardTotal, int serverCount); CompletionStage setStats(List shardServerCounts); diff --git a/src/main/java/org/discordbots/api/client/impl/DiscordBotListAPIImpl.java b/src/main/java/org/discordbots/api/client/impl/DiscordBotListAPIImpl.java index 546df9a..7aa16ab 100644 --- a/src/main/java/org/discordbots/api/client/impl/DiscordBotListAPIImpl.java +++ b/src/main/java/org/discordbots/api/client/impl/DiscordBotListAPIImpl.java @@ -20,6 +20,14 @@ import java.util.concurrent.CompletionStage; import java.util.stream.Collectors; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + public class DiscordBotListAPIImpl implements DiscordBotListAPI { private static final HttpUrl baseUrl = new HttpUrl.Builder() @@ -33,6 +41,10 @@ public class DiscordBotListAPIImpl implements DiscordBotListAPI { private final String token, botId; + private final ScheduledExecutorService autoposterScheduler; + private ScheduledFuture autoposterFuture; + private final AtomicBoolean isAutoposterCancelled; + public DiscordBotListAPIImpl(String token, String botId) { this.token = token; this.botId = botId; @@ -49,6 +61,65 @@ public DiscordBotListAPIImpl(String token, String botId) { return chain.proceed(req); }) .build(); + + this.autoposterScheduler = Executors.newSingleThreadScheduledExecutor(); + this.autoposterFuture = null; + this.isAutoposterCancelled = new AtomicBoolean(false); + } + + @Override + public void startAutoposter(int delayInSeconds, Supplier statsCallback, BiConsumer postCallback) { + if (this.autoposterFuture != null && !this.autoposterFuture.isCancelled()) { + return; + } + + if (delayInSeconds < 900) { + delayInSeconds = 900; + } + + this.autoposterFuture = this.autoposterScheduler.scheduleAtFixedRate(() -> { + if (!this.isAutoposterCancelled.get()) { + final long serverCount = statsCallback.get(); + final CompletionStage response = this.setStats(serverCount); + + if (postCallback != null) { + response.whenComplete((_, error) -> { + if (error == null) { + postCallback.accept(serverCount, null); + } else { + postCallback.accept(null, error); + this.stopAutoposter(); + } + }); + } + } + }, 0, delayInSeconds, TimeUnit.SECONDS); + } + + @Override + public void startAutoposter(int delayInSeconds, Supplier statsCallback) { + this.startAutoposter(delayInSeconds, statsCallback, null); + } + + @Override + public void startAutoposter(Supplier statsCallback, BiConsumer postCallback) { + this.startAutoposter(900, statsCallback, postCallback); + } + + @Override + public void startAutoposter(Supplier statsCallback) { + this.startAutoposter(900, statsCallback, null); + } + + @Override + public void stopAutoposter() { + this.isAutoposterCancelled.set(true); + + if (this.autoposterFuture != null) { + this.autoposterFuture.cancel(false); + } + + this.autoposterScheduler.shutdownNow(); } public CompletionStage setStats(int shardId, int shardTotal, int serverCount) {