Skip to content
This repository was archived by the owner on Feb 22, 2021. It is now read-only.
Draft
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: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
apply plugin: 'java-library'

group 'de.comroid'
version '1.3.3.1-SNAPSHOT'
version '1.3.4-SNAPSHOT'

System.out.println("##teamcity[buildNumber '$version']")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public final class CommandHandler implements
static final String NO_GROUP = "@NoGroup#";

private final DiscordApi api;
private final ResponseManager responseManager;
private final Map<String, CommandRepresentation> commands = new ConcurrentHashMap<>();
private final Map<Long, long[]> responseMap = new ConcurrentHashMap<>();

Expand All @@ -93,6 +94,8 @@ public CommandHandler(DiscordApi api) {
public CommandHandler(DiscordApi api, boolean handleMessageEdit) {
this.api = api;

this.responseManager = new ResponseManager(api);

prefixes = new String[]{"!"};
autoDeleteResponseOnCommandDeletion = true;
customPrefixProvider = null;
Expand Down Expand Up @@ -544,10 +547,12 @@ else if (!message.isPrivateMessage() && !cmd.enableServerChat)
problems.add("This command can only run in an NSFW marked channel!");

if (problems.size() > 0) {
applyResponseDeletion(message.getId(), channel.sendMessage(DefaultEmbedFactory.create()
channel.sendMessage(DefaultEmbedFactory.create()
.setColor(Color.RED)
.setDescription(String.join("\n", problems)))
.exceptionally(get()));
.thenAccept(msg -> responseManager.accept(msg, message))
.exceptionally(get());

return;
}

Expand Down Expand Up @@ -703,7 +708,7 @@ else if (commandRep.convertStringResultsToEmbed && reply instanceof String)
else msgFut = channel.sendMessage(String.valueOf(reply));

if (msgFut != null)
applyResponseDeletion(message.getId(), msgFut.exceptionally(get()));
msgFut.thenAccept(msg -> responseManager.accept(msg, message));
}
}

Expand Down Expand Up @@ -749,6 +754,7 @@ else if (Command.Parameters.class.isAssignableFrom(klasse))
return method.invoke(invocationTarget, args);
}

@Deprecated
private void applyResponseDeletion(long cmdMsgId, CompletableFuture<Message> message) {
message.thenAcceptAsync(msg -> {
if (autoDeleteResponseOnCommandDeletion)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package de.comroid.javacord.util.commands;

import java.io.Closeable;
import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import org.apache.logging.log4j.Logger;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.message.Message;
import org.javacord.core.util.logging.LoggerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ResponseManager implements Consumer<Message>, BiConsumer<Message, Duration>, Closeable {
private static final Logger LOG = LoggerUtil.getLogger(ResponseManager.class);

private final DiscordApi api;

private final Collection<Long> deleteOnShutdown = new HashSet<>();
private final Map<Long, Long> dependencyMap = new ConcurrentHashMap<>();

public ResponseManager(DiscordApi api) {
this.api = api;

Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}

public void accept(final @NotNull Message message, @NotNull Message dependency) {
dependency.addMessageDeleteListener(event -> message.delete().whenComplete((nil, thr) -> {
if (thr != null)
LOG.warn("Could not delete message on-dependency");
}));
}

@Override
public void accept(final @NotNull Message message, Duration timeToLive) {
if (timeToLive.isZero())
deleteOnShutdown.add(message.getId());
else if (timeToLive.isNegative())
message.delete().whenComplete((nil, thr) -> {
if (thr != null)
LOG.warn("Could not delete message instantly", thr);
});
else {
api.getThreadPool().getScheduler()
.schedule(() -> message.delete().whenComplete((nil, thr) -> {
if (thr != null)
LOG.warn("Could not delete message on-timeout", thr);
}), timeToLive.toMillis(), TimeUnit.MILLISECONDS);
}
}

@Override
public void accept(@NotNull Message message) {
accept(message, Duration.ZERO);
}

@Override
public void close() {
if (deleteOnShutdown.size() == 0)
return;

deleteOnShutdown.stream()
.map(api::getCachedMessageById)
.filter(Optional::isPresent)
.map(Optional::get)
.map(msg -> (Runnable) () -> msg.delete().whenComplete((nil, thr) -> {
if (thr != null)
LOG.warn("Could not delete message on-shutdown", thr);
}))
.forEach(api.getThreadPool().getDaemonScheduler()::execute);

deleteOnShutdown.clear();
}
}