From b9cab5a79a9fcfa2447f3a34d734aa7412f2b800 Mon Sep 17 00:00:00 2001 From: danthe1st Date: Tue, 25 Mar 2025 23:11:52 +0100 Subject: [PATCH] add rate limit to staff activity monitor --- .../staff_activity/StaffActivityService.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/net/discordjug/javabot/systems/staff_activity/StaffActivityService.java b/src/main/java/net/discordjug/javabot/systems/staff_activity/StaffActivityService.java index 7bd925228..84652d5ad 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_activity/StaffActivityService.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_activity/StaffActivityService.java @@ -1,8 +1,13 @@ package net.discordjug.javabot.systems.staff_activity; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Service; @@ -29,6 +34,7 @@ public class StaffActivityService { private final BotConfig botConfig; private final StaffActivityMessageRepository repository; + private final Map lastActivities = new ConcurrentHashMap<>(); /** * Updates the staff activity message or creates it if necessary. @@ -43,6 +49,17 @@ public void updateStaffActivity(StaffActivityType type, TemporalAccessor timesta if (staffActivityChannel == null) { return; } + Instant now = Instant.now(); + Instant merged = lastActivities.merge(new StaffActivityKey(member.getGuild().getIdLong(), member.getIdLong(), type), now, (oldValue, currentInstant) -> { + if (timeDifferenceIsBelowRateLimit(oldValue, currentInstant)) { + // less than 5 minutes since insertion + return oldValue; + } + return currentInstant; + }); + if (!merged.equals(now)) { + return; + } Long msgId = repository.getMessageId(staffActivityChannel.getGuild().getIdLong(), member.getIdLong()); if (msgId != null) { staffActivityChannel @@ -53,6 +70,12 @@ public void updateStaffActivity(StaffActivityType type, TemporalAccessor timesta } else { createNewMessage(staffActivityChannel, member, type, timestamp); } + lastActivities.entrySet() + .removeIf(e -> !timeDifferenceIsBelowRateLimit(e.getValue(),now)); + } + + private boolean timeDifferenceIsBelowRateLimit(Instant oldValue, Instant currentInstant) { + return Duration.between(oldValue, currentInstant).minus(Duration.of(5, ChronoUnit.MINUTES)).isNegative(); } private void replaceActivityMessage(StaffActivityType type, TemporalAccessor timestamp, Message activityMessage, Member member) { @@ -96,4 +119,6 @@ private MessageEmbed createEmptyStaffActivityEmbed(Member member) { .setFooter(member.getId()) .build(); } + + private record StaffActivityKey(long guildId, long memberId, StaffActivityType type) {} }