From 040db6745407d2a3519441c79b379ac092399bbb Mon Sep 17 00:00:00 2001 From: Octavia Togami Date: Sat, 19 Sep 2026 19:27:09 -0700 Subject: [PATCH] Use a leading-edge debounce for bans This ensures a spam flood doesn't cause us to also flood Discord with bans, or users with DMs. --- .../org/enginehub/discord/util/PunishmentUtil.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/enginehub/discord/util/PunishmentUtil.java b/src/main/java/org/enginehub/discord/util/PunishmentUtil.java index 62dc6f6..251c294 100644 --- a/src/main/java/org/enginehub/discord/util/PunishmentUtil.java +++ b/src/main/java/org/enginehub/discord/util/PunishmentUtil.java @@ -22,6 +22,8 @@ package org.enginehub.discord.util; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -30,6 +32,12 @@ public final class PunishmentUtil { + private record BanKey(long guildId, long userId) { } + + private static final Cache RECENT_BANS = CacheBuilder.newBuilder() + .expireAfterAccess(1, TimeUnit.MINUTES) + .build(); + private static String getContactString() { return "Submit an appeal via https://ehub.to/ban-appeal if you wish to appeal."; } @@ -44,6 +52,10 @@ public static void kickUser(Guild guild, Member member, String reason) { } public static void banUser(Guild guild, User user, String reason, boolean eraseHistory) { + if (RECENT_BANS.asMap().putIfAbsent(new BanKey(guild.getIdLong(), user.getIdLong()), Boolean.TRUE) != null) { + return; + } + var _ = user.openPrivateChannel().submit() .thenCompose(privateChannel -> privateChannel.sendMessage("You have been banned for `" + reason + "`. " + getContactString())