Skip to content

Commit e985696

Browse files
Merge remote-tracking branch 'origin/main' into main
2 parents 957ee2e + fa6bbcb commit e985696

File tree

9 files changed

+153
-78
lines changed

9 files changed

+153
-78
lines changed

src/main/java/net/javadiscord/javabot/Bot.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import net.javadiscord.javabot.data.config.BotConfig;
1616
import net.javadiscord.javabot.data.h2db.DbHelper;
1717
import net.javadiscord.javabot.data.h2db.message_cache.MessageCache;
18+
import net.javadiscord.javabot.data.h2db.message_cache.MessageCacheListener;
1819
import net.javadiscord.javabot.listener.*;
1920
import net.javadiscord.javabot.systems.help.HelpChannelListener;
2021
import net.javadiscord.javabot.systems.moderation.AutoMod;
@@ -126,6 +127,7 @@ public static void main(String[] args) throws Exception {
126127
*/
127128
private static void addEventListeners(JDA jda) {
128129
jda.addEventListener(
130+
new MessageCacheListener(),
129131
new GitHubLinkListener(),
130132
new MessageLinkListener(),
131133
new GuildJoinListener(),

src/main/java/net/javadiscord/javabot/data/h2db/commands/DbAdminCommandHandler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import net.dv8tion.jda.api.interactions.commands.Command;
55
import net.dv8tion.jda.api.requests.restaction.interactions.AutoCompleteCallbackAction;
66
import net.javadiscord.javabot.command.DelegatingCommandHandler;
7-
import net.javadiscord.javabot.data.h2db.commands.message_cache.MessageCacheInfoSubcommand;
8-
import java.util.Map;
97
import net.javadiscord.javabot.command.interfaces.Autocompletable;
8+
import net.javadiscord.javabot.data.h2db.commands.message_cache.MessageCacheInfoSubcommand;
109
import net.javadiscord.javabot.util.AutocompleteUtils;
10+
1111
import java.util.List;
12+
import java.util.Map;
1213

1314
/**
1415
* Handler class for all Database related commands.

src/main/java/net/javadiscord/javabot/data/h2db/commands/message_cache/MessageCacheInfoSubcommand.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ public InteractionCallbackAction<InteractionHook> handleSlashCommandInteraction(
2323

2424
private MessageEmbed buildInfoEmbed(GuildConfig config, User author) {
2525
long messages = DbActions.count("SELECT count(*) FROM message_cache");
26-
int maxMessages = config.getMessageCache().getMaxCachedMessages();
26+
int maxDatabaseMessages = config.getMessageCache().getMaxCachedMessages();
27+
int maxMemoryMessages = config.getMessageCache().getMessageSynchronizationInterval();
2728
return new EmbedBuilder()
2829
.setAuthor(author.getAsTag(), null, author.getEffectiveAvatarUrl())
2930
.setTitle("Message Cache Info")
3031
.setColor(config.getSlashCommand().getDefaultColor())
3132
.addField("Table Size", DbActions.getLogicalSize("message_cache") + " bytes", true)
32-
.addField("Cached Messages", String.format("%s/%s (%s%%)", messages, maxMessages, ((float) messages / maxMessages) * 100), true)
33+
.addField("Cached (Memory)", String.format("%s/%s (%.2f%%)", Bot.messageCache.cache.size(), maxMemoryMessages, ((float) Bot.messageCache.cache.size() / maxMemoryMessages) * 100), false)
34+
.addField("Cached (Database)", String.format("%s/%s (%.2f%%)", messages, maxDatabaseMessages, ((float) messages / maxDatabaseMessages) * 100), true)
3335
.build();
3436
}
3537
}

src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCache.java

Lines changed: 50 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
import lombok.extern.slf4j.Slf4j;
44
import net.dv8tion.jda.api.EmbedBuilder;
55
import net.dv8tion.jda.api.entities.*;
6-
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
7-
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
8-
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
9-
import net.dv8tion.jda.api.hooks.ListenerAdapter;
106
import net.dv8tion.jda.api.interactions.components.buttons.Button;
117
import net.dv8tion.jda.api.requests.restaction.MessageAction;
128
import net.javadiscord.javabot.Bot;
@@ -17,7 +13,6 @@
1713
import net.javadiscord.javabot.systems.commands.IdCalculatorCommand;
1814
import net.javadiscord.javabot.util.GuildUtils;
1915
import net.javadiscord.javabot.util.TimeUtils;
20-
import org.jetbrains.annotations.NotNull;
2116

2217
import java.io.ByteArrayInputStream;
2318
import java.io.InputStream;
@@ -29,14 +24,16 @@
2924
import java.time.format.DateTimeFormatter;
3025
import java.util.ArrayList;
3126
import java.util.List;
32-
import java.util.Optional;
3327

3428
/**
3529
* Listens for Incoming Messages and stores them in the Message Cache.
3630
*/
3731
@Slf4j
38-
public class MessageCache extends ListenerAdapter {
39-
List<CachedMessage> cache = new ArrayList<>();
32+
public class MessageCache {
33+
/**
34+
* A memory-cache (list) of sent Messages, wrapped to a {@link CachedMessage} object.
35+
*/
36+
public List<CachedMessage> cache = new ArrayList<>();
4037
/**
4138
* Amount of messages since the last synchronization.
4239
* <p>
@@ -68,85 +65,60 @@ public void synchronize() {
6865
});
6966
}
7067

71-
@Override
72-
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
73-
if (this.ignoreMessageCache(event.getMessage())) return;
74-
MessageCacheConfig config = Bot.config.get(event.getGuild()).getMessageCache();
68+
/**
69+
* Caches a single {@link Message} object.
70+
*
71+
* @param message The message to cache.
72+
*/
73+
public void cache(Message message) {
74+
MessageCacheConfig config = Bot.config.get(message.getGuild()).getMessageCache();
7575
if (cache.size() + 1 > config.getMaxCachedMessages()) {
7676
cache.remove(0);
7777
}
7878
if (messageCount >= config.getMessageSynchronizationInterval()) {
7979
synchronize();
8080
}
8181
messageCount++;
82-
cache.add(CachedMessage.of(event.getMessage()));
82+
cache.add(CachedMessage.of(message));
8383
}
8484

85-
@Override
86-
public void onMessageUpdate(@NotNull MessageUpdateEvent event) {
87-
if (this.ignoreMessageCache(event.getMessage())) return;
88-
Optional<CachedMessage> optional = cache.stream().filter(m -> m.getMessageId() == event.getMessageIdLong()).findFirst();
89-
CachedMessage before;
90-
if (optional.isPresent()) {
91-
before = optional.get();
92-
cache.set(cache.indexOf(before), CachedMessage.of(event.getMessage()));
93-
} else {
94-
before = new CachedMessage();
95-
before.setMessageId(event.getMessageIdLong());
96-
before.setMessageContent("[unknown content]");
97-
cache.add(CachedMessage.of(event.getMessage()));
98-
}
99-
if (event.getMessage().getContentRaw().trim().equals(before.getMessageContent())) return;
100-
MessageAction action = GuildUtils.getCacheLogChannel(event.getGuild())
101-
.sendMessageEmbeds(this.buildMessageEditEmbed(event.getGuild(), event.getAuthor(), event.getChannel(), before, event.getMessage()))
102-
.setActionRow(Button.link(event.getMessage().getJumpUrl(), "Jump to Message"));
103-
if (before.getMessageContent().length() > MessageEmbed.VALUE_MAX_LENGTH || event.getMessage().getContentRaw().length() > MessageEmbed.VALUE_MAX_LENGTH) {
104-
action.addFile(this.buildEditedMessageFile(event.getAuthor(), before, event.getMessage()), before.getMessageId() + ".txt");
85+
/**
86+
* Sends the updated message's content to the {@link MessageCacheConfig#getMessageCacheLogChannel()}.
87+
*
88+
* @param updated The new {@link Message}.
89+
* @param before The {@link CachedMessage}.
90+
*/
91+
public void sendUpdatedMessageToLog(Message updated, CachedMessage before) {
92+
if (updated.getContentRaw().trim().equals(before.getMessageContent())) return;
93+
MessageAction action = GuildUtils.getCacheLogChannel(updated.getGuild())
94+
.sendMessageEmbeds(this.buildMessageEditEmbed(updated.getGuild(), updated.getAuthor(), updated.getChannel(), before, updated))
95+
.setActionRow(Button.link(updated.getJumpUrl(), "Jump to Message"));
96+
if (before.getMessageContent().length() > MessageEmbed.VALUE_MAX_LENGTH || updated.getContentRaw().length() > MessageEmbed.VALUE_MAX_LENGTH) {
97+
action.addFile(this.buildEditedMessageFile(updated.getAuthor(), before, updated), before.getMessageId() + ".txt");
10598
}
10699
action.queue();
107100
}
108101

109-
@Override
110-
public void onMessageDelete(@NotNull MessageDeleteEvent event) {
111-
Optional<CachedMessage> optional = cache.stream().filter(m -> m.getMessageId() == event.getMessageIdLong()).findFirst();
112-
if (optional.isPresent()) {
113-
CachedMessage message = optional.get();
114-
event.getJDA().retrieveUserById(message.getAuthorId()).queue(author -> {
115-
MessageAction action = GuildUtils.getCacheLogChannel(event.getGuild())
116-
.sendMessageEmbeds(this.buildMessageDeleteEmbed(event.getGuild(), author, event.getChannel(), message));
117-
if (message.getMessageContent().length() > MessageEmbed.VALUE_MAX_LENGTH) {
118-
action.addFile(this.buildDeletedMessageFile(author, message), message.getMessageId() + ".txt");
119-
}
120-
action.queue();
121-
});
122-
cache.remove(message);
123-
} else {
124-
GuildUtils.getCacheLogChannel(event.getGuild()).sendMessageEmbeds(buildMessageNotCachedEmbed(event.getGuild(), event.getChannel(), event.getMessageIdLong())).queue();
125-
}
126-
}
127-
128102
/**
129-
* Checks whether the given message should be ignored by the cache.
103+
* Sends the deleted message's content to the {@link MessageCacheConfig#getMessageCacheLogChannel()}.
130104
*
131-
* This is done with the following criteria:
132-
* <ol>
133-
* <li>Message author is a bot</li>
134-
* <li>Message author is a system account</li>
135-
* <li>Message author is part of the excluded users</li>
136-
* <li>Channel is excluded from the cache</li>
137-
* </ol>
138-
*
139-
* @param message The message to check
140-
* @return true if any of the criteria above apply
105+
* @param guild The message's {@link Guild}.
106+
* @param channel The message's {@link MessageChannel}.
107+
* @param message The {@link CachedMessage}.
141108
*/
142-
private boolean ignoreMessageCache(Message message) {
143-
MessageCacheConfig config = Bot.config.get(message.getGuild()).getMessageCache();
144-
return message.getAuthor().isBot() || message.getAuthor().isSystem() ||
145-
config.getExcludedUsers().contains(message.getAuthor().getIdLong()) ||
146-
config.getExcludedChannels().contains(message.getChannel().getIdLong());
109+
public void sendDeletedMessageToLog(Guild guild, MessageChannel channel, CachedMessage message) {
110+
guild.getJDA().retrieveUserById(message.getAuthorId()).queue(author -> {
111+
MessageAction action = GuildUtils.getCacheLogChannel(guild)
112+
.sendMessageEmbeds(this.buildMessageDeleteEmbed(guild, author, channel, message));
113+
if (message.getMessageContent().length() > MessageEmbed.VALUE_MAX_LENGTH) {
114+
action.addFile(this.buildDeletedMessageFile(author, message), message.getMessageId() + ".txt");
115+
}
116+
action.queue();
117+
});
118+
cache.remove(message);
147119
}
148120

149-
private EmbedBuilder buildMessageCacheEmbed(MessageChannel channel, CachedMessage before){
121+
private EmbedBuilder buildMessageCacheEmbed(MessageChannel channel, CachedMessage before) {
150122
long epoch = IdCalculatorCommand.getTimestampFromId(before.getMessageId()) / 1000;
151123
return new EmbedBuilder()
152124
.addField("Channel", channel.getAsMention(), true)
@@ -182,7 +154,15 @@ private MessageEmbed buildMessageDeleteEmbed(Guild guild, User author, MessageCh
182154
.build();
183155
}
184156

185-
private MessageEmbed buildMessageNotCachedEmbed(Guild guild, MessageChannel channel, long messageId) {
157+
/**
158+
* Builds a {@link MessageEmbed} object that is used for messages, that were deleted but not cached.
159+
*
160+
* @param guild The message's guild.
161+
* @param channel The message's channel.
162+
* @param messageId The message's id.
163+
* @return The fully-built {@link MessageEmbed} object.
164+
*/
165+
public MessageEmbed buildMessageNotCachedEmbed(Guild guild, MessageChannel channel, long messageId) {
186166
CachedMessage message = new CachedMessage();
187167
message.setMessageId(messageId);
188168
return buildMessageCacheEmbed(channel, message)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package net.javadiscord.javabot.data.h2db.message_cache;
2+
3+
import net.dv8tion.jda.api.entities.Message;
4+
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
5+
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
6+
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
7+
import net.dv8tion.jda.api.hooks.ListenerAdapter;
8+
import net.javadiscord.javabot.Bot;
9+
import net.javadiscord.javabot.data.config.guild.MessageCacheConfig;
10+
import net.javadiscord.javabot.data.h2db.message_cache.model.CachedMessage;
11+
import net.javadiscord.javabot.util.GuildUtils;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
import java.util.List;
15+
import java.util.Optional;
16+
17+
/**
18+
* Listener class that listens for incoming, updated or deleted messages.
19+
*/
20+
public class MessageCacheListener extends ListenerAdapter {
21+
22+
@Override
23+
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
24+
if (this.ignoreMessageCache(event.getMessage())) return;
25+
Bot.messageCache.cache(event.getMessage());
26+
}
27+
28+
@Override
29+
public void onMessageUpdate(@NotNull MessageUpdateEvent event) {
30+
if (this.ignoreMessageCache(event.getMessage())) return;
31+
List<CachedMessage> cache = Bot.messageCache.cache;
32+
Optional<CachedMessage> optional = cache.stream().filter(m -> m.getMessageId() == event.getMessageIdLong()).findFirst();
33+
CachedMessage before;
34+
if (optional.isPresent()) {
35+
before = optional.get();
36+
cache.set(cache.indexOf(before), CachedMessage.of(event.getMessage()));
37+
} else {
38+
before = new CachedMessage();
39+
before.setMessageId(event.getMessageIdLong());
40+
before.setMessageContent("[unknown content]");
41+
Bot.messageCache.cache(event.getMessage());
42+
}
43+
Bot.messageCache.sendUpdatedMessageToLog(event.getMessage(), before);
44+
}
45+
46+
@Override
47+
public void onMessageDelete(@NotNull MessageDeleteEvent event) {
48+
Optional<CachedMessage> optional = Bot.messageCache.cache.stream().filter(m -> m.getMessageId() == event.getMessageIdLong()).findFirst();
49+
if (optional.isPresent()) {
50+
Bot.messageCache.sendDeletedMessageToLog(event.getGuild(), event.getChannel(), optional.get());
51+
} else {
52+
GuildUtils.getCacheLogChannel(event.getGuild())
53+
.sendMessageEmbeds(Bot.messageCache.buildMessageNotCachedEmbed(event.getGuild(), event.getChannel(), event.getMessageIdLong()))
54+
.queue();
55+
}
56+
}
57+
58+
59+
/**
60+
* Checks whether the given message should be ignored by the cache.
61+
* <p>
62+
* This is done with the following criteria:
63+
* <ol>
64+
* <li>Message author is a bot</li>
65+
* <li>Message author is a system account</li>
66+
* <li>Message author is part of the excluded users</li>
67+
* <li>Channel is excluded from the cache</li>
68+
* </ol>
69+
*
70+
* @param message The message to check
71+
* @return true if any of the criteria above apply
72+
*/
73+
private boolean ignoreMessageCache(Message message) {
74+
MessageCacheConfig config = Bot.config.get(message.getGuild()).getMessageCache();
75+
return message.getAuthor().isBot() || message.getAuthor().isSystem() ||
76+
config.getExcludedUsers().contains(message.getAuthor().getIdLong()) ||
77+
config.getExcludedChannels().contains(message.getChannel().getIdLong());
78+
}
79+
80+
}

src/main/java/net/javadiscord/javabot/systems/help/dao/HelpTransactionRepository.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import lombok.extern.slf4j.Slf4j;
55
import net.javadiscord.javabot.systems.help.model.HelpTransaction;
66

7-
import java.sql.*;
7+
import java.sql.Connection;
8+
import java.sql.PreparedStatement;
9+
import java.sql.ResultSet;
10+
import java.sql.SQLException;
811
import java.util.ArrayList;
912
import java.util.List;
1013
import java.util.Optional;

src/main/java/net/javadiscord/javabot/systems/help/model/HelpAccount.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import net.dv8tion.jda.api.entities.Guild;
55
import net.javadiscord.javabot.Bot;
66

7-
import java.util.*;
7+
import java.util.Comparator;
8+
import java.util.Map;
9+
import java.util.Optional;
810

911
/**
1012
* Data class that represents a single Help User Account.

src/main/java/net/javadiscord/javabot/systems/qotw/submissions/subcommands/MarkBestAnswerSubcommand.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package net.javadiscord.javabot.systems.qotw.submissions.subcommands;
22

33
import net.dv8tion.jda.api.EmbedBuilder;
4-
import net.dv8tion.jda.api.entities.*;
4+
import net.dv8tion.jda.api.entities.Member;
5+
import net.dv8tion.jda.api.entities.Message;
6+
import net.dv8tion.jda.api.entities.MessageEmbed;
7+
import net.dv8tion.jda.api.entities.ThreadChannel;
58
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
69
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
710
import net.dv8tion.jda.api.interactions.InteractionHook;

src/main/java/net/javadiscord/javabot/systems/staff/suggestions/SuggestionSubcommand.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.javadiscord.javabot.systems.staff.suggestions;
22

3-
import net.dv8tion.jda.api.entities.*;
3+
import net.dv8tion.jda.api.entities.ChannelType;
4+
import net.dv8tion.jda.api.entities.Message;
5+
import net.dv8tion.jda.api.entities.TextChannel;
46
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
57
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
68
import net.dv8tion.jda.api.interactions.components.ActionRow;

0 commit comments

Comments
 (0)