From 1b0dfa0f47a2f9bc8acd4b96893697460e3539fe Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 10:24:59 +0530
Subject: [PATCH 01/16] Add JOOQ-based data access classes for guilds and
messages
Introduces GuildDataAccess and MessageDataAccess classes using JOOQ for database operations. Updates pom.xml to include the JOOQ dependency and modifies .gitignore to exclude the .idea directory. These changes provide structured data access for guild and message management, including registration, retrieval, and message encryption.
---
.gitignore | 1 +
pom.xml | 5 ++
.../papertrail/database/GuildDataAccess.java | 82 +++++++++++++++++++
.../database/MessageDataAccess.java | 65 +++++++++++++++
4 files changed, 153 insertions(+)
create mode 100644 src/main/java/org/papertrail/database/GuildDataAccess.java
create mode 100644 src/main/java/org/papertrail/database/MessageDataAccess.java
diff --git a/.gitignore b/.gitignore
index 128ac1af..43376ce4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -225,3 +225,4 @@ buildNumber.properties
# Custom
.idea/discord.xml
.env
+/.idea
diff --git a/pom.xml b/pom.xml
index 3499f6f8..8f2f9d55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,11 @@
postgresql
42.7.7
+
+ org.jooq
+ jooq
+ 3.20.5
+
org.apache.commons
commons-lang3
diff --git a/src/main/java/org/papertrail/database/GuildDataAccess.java b/src/main/java/org/papertrail/database/GuildDataAccess.java
new file mode 100644
index 00000000..62faa32e
--- /dev/null
+++ b/src/main/java/org/papertrail/database/GuildDataAccess.java
@@ -0,0 +1,82 @@
+package org.papertrail.database;
+
+import org.jooq.DSLContext;
+
+import java.util.List;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.selectOne;
+import static org.jooq.impl.DSL.table;
+
+public class GuildDataAccess {
+
+ private final DSLContext dsl;
+
+ private static final String GUILD_ID_COLUMN = "guild_id";
+ private static final String CHANNEL_ID_COLUMN = "channel_id";
+
+ public GuildDataAccess(DSLContext dsl) {
+ this.dsl = dsl;
+ }
+
+ public void registerGuildAndChannel(String guildId, String channelId, String tableName) {
+
+ dsl.insertInto(table(tableName))
+ .columns(field(GUILD_ID_COLUMN), field(CHANNEL_ID_COLUMN))
+ .values(Long.parseLong(guildId), Long.parseLong(channelId))
+ .onConflictDoNothing()
+ .execute();
+
+ }
+
+ public List retrieveAllRegisteredGuilds(String tableName) {
+
+ return dsl.select(field(GUILD_ID_COLUMN))
+ .from(table(tableName))
+ .fetch(r -> String.valueOf(r.get(GUILD_ID_COLUMN)));
+
+ }
+
+ public List retrieveAllRegisteredChannels(String tableName) {
+
+ return dsl.select(field(CHANNEL_ID_COLUMN))
+ .from(table(tableName))
+ .fetch(r -> String.valueOf(r.get(CHANNEL_ID_COLUMN)));
+
+ }
+
+ public String retrieveRegisteredChannel (String guildId, String tableName) {
+
+ return dsl.select(field(CHANNEL_ID_COLUMN))
+ .from(table(tableName))
+ .where(field(GUILD_ID_COLUMN).eq(Long.parseLong(guildId)))
+ .fetchOneInto(String.class);
+ }
+
+ public boolean isGuildRegistered (String guildId, String tableName) {
+
+ return dsl.fetchExists(
+ selectOne()
+ .from(tableName)
+ .where(field(GUILD_ID_COLUMN).eq(Long.parseLong(guildId)))
+ );
+
+ }
+
+ public boolean isChannelRegistered (String channelId, String tableName) {
+
+ return dsl.fetchExists(
+ selectOne()
+ .from(tableName)
+ .where(field(CHANNEL_ID_COLUMN).eq(Long.parseLong(channelId)))
+ );
+ }
+
+ public void unregister (String guildId, String tableName) {
+
+ dsl.deleteFrom(table(tableName))
+ .where(field(GUILD_ID_COLUMN).eq(Long.parseLong(guildId)))
+ .execute();
+ }
+
+}
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
new file mode 100644
index 00000000..93784fd1
--- /dev/null
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -0,0 +1,65 @@
+package org.papertrail.database;
+
+import org.jooq.DSLContext;
+import org.papertrail.utilities.MessageEncryption;
+
+import java.util.Map;
+import java.util.Objects;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.selectOne;
+import static org.jooq.impl.DSL.table;
+
+public class MessageDataAccess {
+
+ private final DSLContext dsl;
+
+ private static final String MESSAGE_ID_COLUMN = "message_id";
+ private static final String MESSAGE_CONTENT_COLUMN = "message_content";
+ private static final String AUTHOR_ID_COLUMN = "author_id";
+
+ public MessageDataAccess (DSLContext dsl) {
+ this.dsl = dsl;
+ }
+
+ public void logMessage(String messageId, String messageContent, String authorId) {
+
+ dsl.insertInto(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
+ .columns(field(MESSAGE_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN), field(AUTHOR_ID_COLUMN))
+ .values(Long.parseLong(messageId), MessageEncryption.encrypt(messageContent), Long.parseLong(authorId))
+ .onConflictDoNothing()
+ .execute();
+ }
+
+ public Map retrieveAuthorAndMessage (String messageId) {
+
+ return dsl.select(field(AUTHOR_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN))
+ .from(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
+ .where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
+ .fetchOne(r ->
+ Map.of(String.valueOf(r.get(field(AUTHOR_ID_COLUMN))), Objects.requireNonNull(MessageEncryption.decrypt(String.valueOf(r.get(field(MESSAGE_CONTENT_COLUMN)))))));
+ }
+
+ public boolean messageExists (String messageId) {
+
+ return dsl.fetchExists(
+ selectOne().from(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
+ .where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
+ );
+ }
+
+ public void updateMessage (String messageId, String messageContent) {
+
+ dsl.update(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
+ .set(field(MESSAGE_CONTENT_COLUMN), MessageEncryption.encrypt(messageContent))
+ .where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
+ .execute();
+ }
+
+ public void deleteMessage (String messageId) {
+
+ dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
+ .where(field(MESSAGE_ID_COLUMN).eq(messageId))
+ .execute();
+ }
+}
From dd98756106a2803090942d8b96c2f0c4e6a732cb Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 11:29:14 +0530
Subject: [PATCH 02/16] Refactor database access to use data access objects
Replaces direct SQL operations in DatabaseConnector with dedicated data access classes (GuildDataAccess, MessageDataAccess) using jOOQ DSL. Updates all listeners and related classes to use the new data access methods, improving modularity and maintainability. Adds AuthorAndMessageEntity for structured message retrieval.
---
.../papertrail/cleanup/BotKickListener.java | 22 +-
.../database/AuthorAndMessageEntity.java | 22 ++
.../database/DatabaseConnector.java | 219 +-----------------
.../database/MessageDataAccess.java | 8 +-
.../customlisteners/AnnouncementListener.java | 3 +-
.../guildlisteners/ServerBoostListener.java | 2 +-
.../loglisteners/AuditLogCommandListener.java | 15 +-
.../loglisteners/AuditLogListener.java | 2 +-
.../GuildMemberJoinAndLeaveListener.java | 4 +-
.../MessageLogCommandListener.java | 15 +-
.../messagelisteners/MessageLogListener.java | 187 +++++++--------
.../voicelisteners/GuildVoiceListener.java | 2 +-
12 files changed, 154 insertions(+), 347 deletions(-)
create mode 100644 src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
diff --git a/src/main/java/org/papertrail/cleanup/BotKickListener.java b/src/main/java/org/papertrail/cleanup/BotKickListener.java
index ee437900..26ec55cd 100644
--- a/src/main/java/org/papertrail/cleanup/BotKickListener.java
+++ b/src/main/java/org/papertrail/cleanup/BotKickListener.java
@@ -1,7 +1,5 @@
package org.papertrail.cleanup;
-import java.sql.SQLException;
-
import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -10,25 +8,27 @@
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.events.guild.GuildLeaveEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
+
/*
* This class will have methods that unregister the log channels from the database after the bot has been kicked
*/
public class BotKickListener extends ListenerAdapter {
-
+
private DatabaseConnector dc;
-
+
public BotKickListener(DatabaseConnector dc) {
- this.dc=dc;
+ this.dc = dc;
}
-
+
@Override
public void onGuildLeave(@NotNull GuildLeaveEvent event) {
- Guild leftGuild = event.getGuild();
try {
- dc.unregisterGuildAndChannel(leftGuild.getId(), TableNames.AUDIT_LOG_TABLE);
- dc.unregisterGuildAndChannel(leftGuild.getId(), TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- } catch (SQLException e) {
- Logger.error(e, "Could not auto-unregister guild upon guild leave: "+event.getGuild().getId()+"/"+event.getGuild().getName());
+ Guild leftGuild = event.getGuild();
+ dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.AUDIT_LOG_TABLE);
+ dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ } catch (Exception e) {
+ Logger.error(e, "Could not auto-unregister guild upon guild leave: " + event.getGuild().getId() + "/"
+ + event.getGuild().getName());
}
}
}
diff --git a/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java b/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
new file mode 100644
index 00000000..736c1085
--- /dev/null
+++ b/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
@@ -0,0 +1,22 @@
+package org.papertrail.database;
+
+public class AuthorAndMessageEntity {
+
+ private final String authorId;
+ private final String messageContent;
+
+ public AuthorAndMessageEntity(String authorId, String messageContent) {
+ super();
+ this.authorId = authorId;
+ this.messageContent = messageContent;
+ }
+
+ public String getAuthorId() {
+ return authorId;
+ }
+
+ public String getMessageContent() {
+ return messageContent;
+ }
+
+}
diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java
index 8dc95eae..d935e020 100644
--- a/src/main/java/org/papertrail/database/DatabaseConnector.java
+++ b/src/main/java/org/papertrail/database/DatabaseConnector.java
@@ -2,230 +2,31 @@
import java.sql.Connection;
import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import org.jooq.DSLContext;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
import org.papertrail.utilities.EnvConfig;
-import org.papertrail.utilities.MessageEncryption;
-import org.tinylog.Logger;
public class DatabaseConnector {
private static final String DB_URL = EnvConfig.get("DATABASEURL");
- private Connection connect;
+ private final DSLContext dsl;
public DatabaseConnector() throws SQLException {
- connect = DriverManager.getConnection(DB_URL);
- }
-
- public void registerGuildAndChannel(String guildId, String channelId, String tableName) throws SQLException {
-
- String sqlStatement = "INSERT INTO "+tableName+" (guild_id, channel_id) VALUES (?, ?)";
-
- try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){
- psmt.setLong(1, Long.parseLong(guildId));
- psmt.setLong(2, Long.parseLong(channelId));
- psmt.executeUpdate();
- }
-
- }
-
- public List retrieveAllRegisteredGuilds(String tableName) {
-
- String sqlStatement = "SELECT guild_id FROM " + tableName;
- List guilds = new ArrayList<>();
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement); ResultSet rs = psmt.executeQuery()) {
- while (rs.next()) {
- guilds.add(String.valueOf(rs.getLong(1)));
- }
-
- return guilds;
- } catch (SQLException e) {
- Logger.error(e, "Could not retrieve registered guilds");
- return Collections.emptyList();
- }
+ Connection connection = DriverManager.getConnection(DB_URL);
+ this.dsl = DSL.using(connection, SQLDialect.POSTGRES);
}
- public List retrieveAllRegisteredChannels(String tableName) {
-
- String sqlStatement = "SELECT channel_id FROM " + tableName;
- List channels = new ArrayList<>();
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement); ResultSet rs = psmt.executeQuery()) {
- while (rs.next()) {
- channels.add(String.valueOf(rs.getLong(1)));
- }
-
- return channels;
- } catch (SQLException e) {
- Logger.error(e, "Could not retrieve registered channels");
- return Collections.emptyList();
- }
- }
-
- public String retrieveRegisteredChannelId(String guildId, String tableName) {
-
- String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE guild_id = ?";
- String channelId = "";
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) {
- psmt.setLong(1, Long.parseLong(guildId));
-
- try (ResultSet rs = psmt.executeQuery()) {
-
- while (rs.next()) { // by configuration, there will always be only one channel id row at a time
- // because registering multiple channels is not allowed
- channelId = String.valueOf(rs.getLong("channel_id"));
- }
- }
- return channelId;
- } catch (SQLException e) {
- Logger.error(e, "Could not retrieve registered guild channel id");
- return null;
- }
- }
- /*
- * If a guild of the given id is found, will return that id, otherwise null
- */
- public String checkGuildRegistration(String guildId, String tableName) {
-
- String sqlStatement = "SELECT guild_id FROM " + tableName + " WHERE guild_id = ?";
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) {
- psmt.setLong(1, Long.parseLong(guildId));
-
- try (ResultSet rs = psmt.executeQuery()) {
-
- while (rs.next()) {
- return String.valueOf(rs.getLong("guild_id"));
-
- }
- }
- return null;
- } catch (SQLException e) {
- Logger.error("Could not retrieve registered guild channel id", e);
- return null;
- }
- }
-
- /*
- * If a channel of the given id is found, will return that id, otherwise null
- */
- public String checkChannelRegistration(String channelId, String tableName) {
-
- String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE channel_id = ?";
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) {
- psmt.setLong(1, Long.parseLong(channelId));
-
- try (ResultSet rs = psmt.executeQuery()) {
- while (rs.next()) {
- return String.valueOf(rs.getLong("guild_id"));
- }
- }
- return null;
- } catch (SQLException e) {
- Logger.error("Could not retrieve registered guild channel id", e);
- return null;
- }
+ public GuildDataAccess getGuildDataAccess() {
+ return new GuildDataAccess(dsl);
}
-
- public void unregisterGuildAndChannel(String guildId, String tableName) throws SQLException {
-
- String sqlStatement = "DELETE FROM "+tableName+" WHERE guild_id = ?";
-
- try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){
- psmt.setLong(1, Long.parseLong(guildId));
- psmt.executeUpdate();
- }
- }
-
- // MESSAGE FUNCTIONS
- public void logMessage(String messageId, String messageContent, String authorId, String tableName) throws SQLException {
-
- String sqlStatement = "INSERT INTO "+tableName+" (message_id, message_content, author_id) VALUES (?, ?, ?)";
-
- try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){
- psmt.setLong(1, Long.parseLong(messageId));
- psmt.setString(2, MessageEncryption.encrypt(messageContent));
- psmt.setLong(3, Long.parseLong(authorId));
- psmt.executeUpdate();
- }
- }
-
- public List retrieveAuthorAndMessage(String messageId, String tableName) {
-
- String sqlStatement = "SELECT author_id, message_content FROM " + tableName + " WHERE message_id = ?";
-
- String messageContent = "";
- String authorId = "";
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) {
- psmt.setLong(1, Long.parseLong(messageId));
-
- try (ResultSet rs = psmt.executeQuery()) {
- if (rs.next()) { // only one message is logged per row per message id
- messageContent = MessageEncryption.decrypt(rs.getString("message_content"));
- authorId = String.valueOf(rs.getLong("author_id"));
- return List.of(authorId, messageContent);
- }
- }
- return Collections.emptyList();
- } catch (SQLException e) {
- Logger.error("Could not retrieve message", e);
- e.printStackTrace();
- return Collections.emptyList();
- }
- }
- /*
- * Checks if the message id exists in the database and returns the same if found, else null
- */
- public String checkMessageId(String messageId, String tableName) {
-
- String sqlStatement = "SELECT message_id FROM " + tableName + " WHERE message_id = ?";
-
- try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) {
- psmt.setLong(1, Long.parseLong(messageId));
-
- try (ResultSet rs = psmt.executeQuery()) {
- if (rs.next()) { // only one message is logged per row per message id
- return String.valueOf(rs.getLong("message_id"));
- }
- }
- return null;
- } catch (SQLException e) {
- Logger.error("Could not retrieve message id", e);
- e.printStackTrace();
- return null;
- }
- }
-
- public void updateMessage(String messageId, String messageContent, String tableName) throws SQLException {
-
- String sqlStatement = "UPDATE " + tableName + " SET message_content = ? WHERE message_id = ?";
-
- try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){
- psmt.setString(1, MessageEncryption.encrypt(messageContent));
- psmt.setLong(2, Long.parseLong(messageId));
- psmt.executeUpdate();
- }
+ public MessageDataAccess getMessageDataAccess() {
+ return new MessageDataAccess(dsl);
}
- public void deleteMessage(String messageId, String tableName) throws SQLException {
-
- String sqlStatement = "DELETE FROM "+tableName+" WHERE message_id = ?";
-
- try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){
- psmt.setLong(1, Long.parseLong(messageId));
- psmt.executeUpdate();
- }
- }
}
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index 93784fd1..5d940be6 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -3,9 +3,6 @@
import org.jooq.DSLContext;
import org.papertrail.utilities.MessageEncryption;
-import java.util.Map;
-import java.util.Objects;
-
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
import static org.jooq.impl.DSL.table;
@@ -31,13 +28,12 @@ public void logMessage(String messageId, String messageContent, String authorId)
.execute();
}
- public Map retrieveAuthorAndMessage (String messageId) {
+ public AuthorAndMessageEntity retrieveAuthorAndMessage (String messageId) {
return dsl.select(field(AUTHOR_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN))
.from(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .fetchOne(r ->
- Map.of(String.valueOf(r.get(field(AUTHOR_ID_COLUMN))), Objects.requireNonNull(MessageEncryption.decrypt(String.valueOf(r.get(field(MESSAGE_CONTENT_COLUMN)))))));
+ .fetchOne(r -> new AuthorAndMessageEntity(String.valueOf(r.get(field(AUTHOR_ID_COLUMN))), MessageEncryption.decrypt(String.valueOf(r.get(field(MESSAGE_CONTENT_COLUMN))))));
}
public boolean messageExists (String messageId) {
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java b/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java
index 7ee5672f..019a2eeb 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java
+++ b/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java
@@ -35,7 +35,8 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
if(event.getName().equals("announcement")) {
- List registeredChannelList = dc.retrieveAllRegisteredChannels(TableNames.AUDIT_LOG_TABLE);
+ List registeredChannelList = dc.getGuildDataAccess().retrieveAllRegisteredChannels(TableNames.AUDIT_LOG_TABLE);
+
if(registeredChannelList.isEmpty()) {
return;
}
diff --git a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
index 5e81ad1a..3bcc4064 100644
--- a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
+++ b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
@@ -27,7 +27,7 @@ public void onGuildMemberUpdateBoostTime(GuildMemberUpdateBoostTimeEvent event)
// this will return a non-null text id if a channel was previously registered in the database
// server boost logs are mapped to audit log table
- String registeredChannelId=dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
if(registeredChannelId==null ||registeredChannelId.isBlank()) {
return;
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java
index bcb07ea2..6c456269 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java
@@ -1,7 +1,6 @@
package org.papertrail.listeners.loglisteners;
import java.awt.Color;
-import java.sql.SQLException;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -59,7 +58,7 @@ private void setAuditLogging(SlashCommandInteractionEvent event) {
String guildId = event.getGuild().getId();
// retrieve the previously registered channel_id associated with the given
// guild_id
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
// if there is a registered channel_id in the database, send a warning message
// in the channel where the command was called from, stating that a channel has
@@ -83,7 +82,7 @@ private void setAuditLogging(SlashCommandInteractionEvent event) {
String channelIdToRegister = event.getChannel().asTextChannel().getId();
try {
// register the channel_id along with guild_id in the database
- dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.AUDIT_LOG_TABLE);
+ dc.getGuildDataAccess().registerGuildAndChannel(guildId, channelIdToRegister, TableNames.AUDIT_LOG_TABLE);
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("π Audit Log Configuration");
@@ -93,7 +92,7 @@ private void setAuditLogging(SlashCommandInteractionEvent event) {
event.replyEmbeds(mb).setEphemeral(false).queue();
- } catch (SQLException e) {
+ } catch (Exception e) {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("π Audit Log Configuration");
@@ -118,7 +117,7 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
String guildId = event.getGuild().getId();
// retrieve the channel_id registered in the database
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
// if there is no channel_id for the given guild_id in the database, then inform
// the user of the same, else link the channel that has been registered
@@ -166,7 +165,7 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
}
String guildId = event.getGuild().getId();
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
@@ -180,7 +179,7 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
} else {
try {
- dc.unregisterGuildAndChannel(guildId, TableNames.AUDIT_LOG_TABLE);
+ dc.getGuildDataAccess().unregister(guildId, TableNames.AUDIT_LOG_TABLE);
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("π Audit Log Configuration");
@@ -190,7 +189,7 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
event.replyEmbeds(mb).setEphemeral(false).queue();
- } catch (SQLException e) {
+ } catch (Exception e) {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("π Audit Log Configuration");
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
index 6c02a65b..2d88f199 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
@@ -45,7 +45,7 @@ public AuditLogListener(DatabaseConnector dc) {
public void onGuildAuditLogEntryCreate(GuildAuditLogEntryCreateEvent event) {
// this will return a non-null text id if a channel was previously registered in the database
- String registeredChannelId=dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
if(registeredChannelId==null ||registeredChannelId.isBlank()) {
return;
diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
index b34770e9..9f243992 100644
--- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
+++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
@@ -29,7 +29,7 @@ public void onGuildMemberJoin(GuildMemberJoinEvent event) {
// this will return a non-null text id if a channel was previously registered in
// the database
// guild member join and leave events are mapped to audit log table
- String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
return;
@@ -62,7 +62,7 @@ public void onGuildMemberRemove(GuildMemberRemoveEvent event) {
// this will return a non-null text id if a channel was previously registered in
// the database
- String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
return;
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java
index 3cb11ebe..0a1bb461 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java
@@ -1,7 +1,6 @@
package org.papertrail.listeners.messagelisteners;
import java.awt.Color;
-import java.sql.SQLException;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -61,7 +60,7 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
String guildId = guild.getId();
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
if(registeredChannelId!=null && !registeredChannelId.isBlank()) {
@@ -79,7 +78,7 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
String channelIdToRegister = event.getChannelId();
try {
// register the channel_id along with guild_id in the database
- dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ dc.getGuildDataAccess().registerGuildAndChannel(guildId, channelIdToRegister, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
eb.addField("β
Channel Registration Success","β°ββ€"+"All edited and deleted messages will be logged here", false);
eb.setColor(Color.GREEN);
@@ -89,7 +88,7 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
eb.clearFields();
- } catch (SQLException e) {
+ } catch (Exception e) {
eb.addField("β Channel Registration Failure","β°ββ€"+"Channel could not be registered", false);
eb.setColor(Color.BLACK);
@@ -116,7 +115,7 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
String guildId = guild.getId();
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
// if there is no channel_id for the given guild_id in the database, then inform
// the user of the same, else link the channel that has been registered
if (registeredChannelId == null || registeredChannelId.isBlank()) {
@@ -157,7 +156,7 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
String guildId = guild.getId();
- String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
eb.addField("βΉοΈ Channel Removal", "β°ββ€"+"No channel has been registered for message logs", false);
@@ -171,7 +170,7 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
} else {
try {
- dc.unregisterGuildAndChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ dc.getGuildDataAccess().unregister(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
eb.addField("β
Channel Removal", "β°ββ€"+"Channel successfully unset", false);
eb.setColor(Color.GREEN);
@@ -180,7 +179,7 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
event.replyEmbeds(mb).setEphemeral(false).queue();
eb.clearFields();
- } catch (SQLException e) {
+ } catch (Exception e) {
eb.addField("β Channel Removal Failure", "β°ββ€"+"Channel could not be unset", false);
eb.setColor(Color.BLACK);
MessageEmbed mb = eb.build();
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
index 93f6726e..eff4492f 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
@@ -1,10 +1,8 @@
package org.papertrail.listeners.messagelisteners;
import java.awt.Color;
-import java.sql.SQLException;
import java.time.Instant;
-import java.util.List;
-
+import org.papertrail.database.AuthorAndMessageEntity;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
import org.tinylog.Logger;
@@ -40,22 +38,18 @@ public void onMessageReceived(MessageReceivedEvent event) {
// get the guild id for which the event was fired
String guildId = event.getGuild().getId();
// see if the guild id is registered in the database for logging
- String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
// if not registered, exit
- if(registeredGuildId==null) {
+ if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) {
return;
}
// else if the registered guild id matches with the event fetched guild id, log the message with its ID and author
- if(registeredGuildId.equals(guildId)) {
- try {
- String messageId = event.getMessageId();
- dc.logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId(), TableNames.MESSAGE_LOG_CONTENT_TABLE);
- } catch (SQLException e) {
- Logger.error(e, "Could not log message");
- e.printStackTrace();
- }
+ try {
+ String messageId = event.getMessageId();
+ dc.getMessageDataAccess().logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId());
+ } catch (Exception e) {
+ Logger.error(e, "Could not log message");
}
}
@@ -69,55 +63,52 @@ public void onMessageUpdate(MessageUpdateEvent event) {
String guildId = event.getGuild().getId();
- String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- if(registeredGuildId==null) {
+ if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) {
return;
}
- if(registeredGuildId.equals(guildId)) {
- try {
- // get the message id of the message which was updated
- String messageId = event.getMessageId();
-
- // fetch the old message content and its author from the database
- List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE);
- if(oldAuthorAndMessage==null || oldAuthorAndMessage.isEmpty()) { // would be true only if the unedited message was not logged in the first place
- return;
- }
- // fetch the updated message from the event
- String updatedMessage = event.getMessage().getContentRaw();
-
- // Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
- // This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
- if(updatedMessage.equals(oldAuthorAndMessage.getLast())) {
- return;
- }
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π Message Edit Event");
- eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
- eb.setColor(Color.YELLOW);
-
- eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author
- eb.addField("New Message", updatedMessage, false);
-
- eb.setFooter(event.getGuild().getName());
- eb.setTimestamp(Instant.now());
- // update the database with the new message
- dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE);
- // the reason this is above the send queue is because in case where the user did not give sufficient permissions to
- // the bot, the error responses wouldn't block the update of the message in the database.
-
- // fetch the channel id from the database
- // this channel is where the logs will be sent to
- // wrap the embed and send
- MessageEmbed mb = eb.build();
- String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
- } catch (SQLException e) {
- Logger.error(e, "Could not log updated message");
- e.printStackTrace();
+ try {
+ // get the message id of the message which was updated
+ String messageId = event.getMessageId();
+
+ // fetch the old message content and its author from the database
+ AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
+ if(ame.getAuthorId()==null || ame.getAuthorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
+ return;
+ }
+ // fetch the updated message and its author from the event
+ String updatedMessage = event.getMessage().getContentRaw();
+
+ // Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
+ // This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
+ if(updatedMessage.equals(ame.getMessageContent())) {
+ return;
}
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("π Message Edit Event");
+ eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
+ eb.setColor(Color.YELLOW);
+
+ eb.addField("Old Message", ame.getMessageContent(), false); // get only the message and not the author
+ eb.addField("New Message", updatedMessage, false);
+
+ eb.setFooter(event.getGuild().getName());
+ eb.setTimestamp(Instant.now());
+ // update the database with the new message
+ dc.getMessageDataAccess().updateMessage(messageId, updatedMessage);
+ // the reason this is above the send queue is because in case where the user did not give sufficient permissions to
+ // the bot, the error responses wouldn't block the update of the message in the database.
+
+ // fetch the channel id from the database
+ // this channel is where the logs will be sent to
+ // wrap the embed and send
+ MessageEmbed mb = eb.build();
+ String channelIdToSendTo = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ } catch (Exception e) {
+ Logger.error(e, "Could not log updated message");
+ e.printStackTrace();
}
}
@@ -126,51 +117,49 @@ public void onMessageDelete(MessageDeleteEvent event) {
String guildId = event.getGuild().getId();
- String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- if(registeredGuildId==null) {
+ if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) {
return;
}
- if(registeredGuildId.equals(guildId)) {
- try {
- // get the message id of the message which was deleted
- String messageId = event.getMessageId();
- // if the message id does not exist in db, it means the message has not been logged in the first place
- if(dc.checkMessageId(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE)==null) {
- return;
- }
-
- // retrieve the channel id where the logs must be sent
- String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- // retrieve the stored message in the database which was deleted
- List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE);
-
- User author = event.getJDA().getUserById(oldAuthorAndMessage.getFirst());
- String mentionableAuthor = (author !=null ? author.getAsMention() : oldAuthorAndMessage.getFirst());
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("ποΈ Message Delete Event");
- eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
- eb.setColor(Color.RED);
- eb.addField("Deleted Message", oldAuthorAndMessage.getLast(), false);
-
- eb.setFooter(event.getGuild().getName());
- eb.setTimestamp(Instant.now());
-
- // delete the message from the database
- dc.deleteMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE);
- // the reason this is above the send queue is because in case where the user did not give sufficient permissions to
- // the bot, the error responses wouldn't block the deletion in the database.
-
- // send the fetched deleted message to the logging channel
- MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
-
- } catch (SQLException e) {
- Logger.error(e, "Could not delete message");
- e.printStackTrace();
-
+ try {
+ // get the message id of the message which was deleted
+ String messageId = event.getMessageId();
+
+ // if the message id does not exist in db, it means the message has not been logged in the first place
+ if(!dc.getMessageDataAccess().messageExists(messageId)) {
+ return;
}
+
+ // retrieve the channel id where the logs must be sent
+ String channelIdToSendTo = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
+ // retrieve the stored message in the database which was deleted
+ AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
+
+ User author = event.getJDA().getUserById(ame.getAuthorId());
+ String mentionableAuthor = (author !=null ? author.getAsMention() : ame.getAuthorId());
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("ποΈ Message Delete Event");
+ eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
+ eb.setColor(Color.RED);
+ eb.addField("Deleted Message", ame.getMessageContent(), false);
+
+ eb.setFooter(event.getGuild().getName());
+ eb.setTimestamp(Instant.now());
+
+ // delete the message from the database
+ dc.getMessageDataAccess().deleteMessage(messageId);
+ // the reason this is above the send queue is because in case where the user did not give sufficient permissions to
+ // the bot, the error responses wouldn't block the deletion in the database.
+
+ // send the fetched deleted message to the logging channel
+ MessageEmbed mb = eb.build();
+ event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+
+ } catch (Exception e) {
+ Logger.error(e, "Could not delete message");
+ e.printStackTrace();
+
}
}
}
diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
index 68faeb85..b63268f1 100644
--- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
+++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
@@ -27,7 +27,7 @@ public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) {
// this will return a non-null text id if a channel was previously registered in
// the database
// guild voice events are mapped to audit log table
- String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
return;
From dbaa763320f0707441e71a3421cd983bc55f6290 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 11:49:51 +0530
Subject: [PATCH 03/16] Fix message deletion by parsing messageId as Long
Updated the deleteMessage method to parse the messageId string to a Long before using it in the where clause. This ensures correct type matching for the MESSAGE_ID_COLUMN in the database.
---
src/main/java/org/papertrail/database/MessageDataAccess.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index 5d940be6..f39596ad 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -55,7 +55,7 @@ public void updateMessage (String messageId, String messageContent) {
public void deleteMessage (String messageId) {
dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
- .where(field(MESSAGE_ID_COLUMN).eq(messageId))
+ .where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
.execute();
}
}
From 906b10a5ecdc16a0bc7cb4a493b658aee9acf85c Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 13:01:55 +0530
Subject: [PATCH 04/16] Make database operations async and improve error
handling
Refactored MessageDataAccess to use asynchronous database operations with executeAsync and added error logging using Tinylog. Updated MessageLogListener to handle null AuthorAndMessageEntity and removed unnecessary printStackTrace calls for cleaner error handling.
---
.../database/MessageDataAccess.java | 19 ++++++++++++++++---
.../messagelisteners/MessageLogListener.java | 7 +++----
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index f39596ad..15d272b8 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -2,6 +2,7 @@
import org.jooq.DSLContext;
import org.papertrail.utilities.MessageEncryption;
+import org.tinylog.Logger;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
@@ -25,7 +26,11 @@ public void logMessage(String messageId, String messageContent, String authorId)
.columns(field(MESSAGE_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN), field(AUTHOR_ID_COLUMN))
.values(Long.parseLong(messageId), MessageEncryption.encrypt(messageContent), Long.parseLong(authorId))
.onConflictDoNothing()
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error logging message to the database. MessageID: {} AuthorID: {}",messageId, authorId);
+ return null;
+ });
}
public AuthorAndMessageEntity retrieveAuthorAndMessage (String messageId) {
@@ -49,13 +54,21 @@ public void updateMessage (String messageId, String messageContent) {
dsl.update(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.set(field(MESSAGE_CONTENT_COLUMN), MessageEncryption.encrypt(messageContent))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error updating message in the database. MessageID: "+messageId);
+ return null;
+ });
}
public void deleteMessage (String messageId) {
dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error deleting message from database. MessageID: "+messageId);
+ return null;
+ });
}
}
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
index eff4492f..6466ef0e 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
@@ -73,7 +73,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
// fetch the old message content and its author from the database
AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
- if(ame.getAuthorId()==null || ame.getAuthorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
+ if(ame==null || ame.getAuthorId()==null || ame.getAuthorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
return;
}
// fetch the updated message and its author from the event
@@ -108,7 +108,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
} catch (Exception e) {
Logger.error(e, "Could not log updated message");
- e.printStackTrace();
+
}
}
@@ -154,11 +154,10 @@ public void onMessageDelete(MessageDeleteEvent event) {
// send the fetched deleted message to the logging channel
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
} catch (Exception e) {
Logger.error(e, "Could not delete message");
- e.printStackTrace();
}
}
From e885605c5ebd38cc76e5b4f066c56b2569adcf77 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 13:12:28 +0530
Subject: [PATCH 05/16] Update MessageLogListener.java
---
.../listeners/messagelisteners/MessageLogListener.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
index 6466ef0e..577198e0 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
@@ -150,7 +150,7 @@ public void onMessageDelete(MessageDeleteEvent event) {
// delete the message from the database
dc.getMessageDataAccess().deleteMessage(messageId);
// the reason this is above the send queue is because in case where the user did not give sufficient permissions to
- // the bot, the error responses wouldn't block the deletion in the database.
+ // the bot, (such as no send message permissions) the exceptions wouldn't block the deletion in the database.
// send the fetched deleted message to the logging channel
MessageEmbed mb = eb.build();
From c17f52a67ecfccc1d6e54059c9d5226f150010ad Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Thu, 17 Jul 2025 14:50:05 +0530
Subject: [PATCH 06/16] Add HikariCP connection pooling
Replaces direct JDBC connections with HikariCP
---
pom.xml | 5 +++
.../database/DatabaseConnector.java | 35 +++++++++++++++----
2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8f2f9d55..c8df87e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,11 @@
dotenv-java
3.2.0
+
+ com.zaxxer
+ HikariCP
+ 6.3.0
+
org.postgresql
postgresql
diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java
index d935e020..577021ed 100644
--- a/src/main/java/org/papertrail/database/DatabaseConnector.java
+++ b/src/main/java/org/papertrail/database/DatabaseConnector.java
@@ -1,23 +1,24 @@
package org.papertrail.database;
-import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.SQLException;
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.papertrail.utilities.EnvConfig;
+import org.tinylog.Logger;
+
+import com.zaxxer.hikari.HikariDataSource;
public class DatabaseConnector {
private static final String DB_URL = EnvConfig.get("DATABASEURL");
-
+ private static HikariDataSource dataSource;
private final DSLContext dsl;
public DatabaseConnector() throws SQLException {
- Connection connection = DriverManager.getConnection(DB_URL);
- this.dsl = DSL.using(connection, SQLDialect.POSTGRES);
+ initializeDataSource();
+ this.dsl = DSL.using(dataSource, SQLDialect.POSTGRES);
}
public GuildDataAccess getGuildDataAccess() {
@@ -27,6 +28,26 @@ public GuildDataAccess getGuildDataAccess() {
public MessageDataAccess getMessageDataAccess() {
return new MessageDataAccess(dsl);
}
-
-
+
+ private static synchronized void initializeDataSource() {
+
+ if (dataSource == null) {
+ dataSource = new HikariDataSource();
+ dataSource.setJdbcUrl(DB_URL);
+ dataSource.setMaximumPoolSize(20); // Adjust as needed
+ dataSource.setMinimumIdle(2); // Adjust as needed
+ dataSource.setConnectionTimeout(30000); // 30 seconds
+ dataSource.setIdleTimeout(600000); // 10 minutes
+ dataSource.setMaxLifetime(1800000); // 30 minutes
+ dataSource.setPoolName("PaperTrailPool");
+ }
+ // Ensure the data source is closed on shutdown
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ if (dataSource != null && !dataSource.isClosed()) {
+ dataSource.close();
+ Logger.info("Database connection pool closed.");
+ }
+ }));
+ }
+
}
From 544095d4e50e3563d5131976ad7da7489c512617 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 12:40:20 +0530
Subject: [PATCH 07/16] Update to JDK 24 and switch to synchronous DB
operations
Switched to JDK24 from 21. Refactored MessageDataAccess to use synchronous database operations instead of async
---
Dockerfile | 6 +++---
pom.xml | 4 ++--
.../database/MessageDataAccess.java | 19 +++----------------
3 files changed, 8 insertions(+), 21 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index f19c3903..1b7b117f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Importing JDK and copying required files
-FROM openjdk:21-jdk AS build
+FROM openjdk:24-jdk AS build
WORKDIR /app
# Copy Maven wrapper
@@ -16,8 +16,8 @@ COPY src ./src
RUN ./mvnw clean package -DskipTests
-# Stage 2: Create the final Docker image using OpenJDK 21
-FROM openjdk:21-jdk
+# Stage 2: Create the final Docker image using OpenJDK 24
+FROM openjdk:24-jdk
WORKDIR /app
VOLUME /tmp
diff --git a/pom.xml b/pom.xml
index c8df87e9..2cd1cf12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
UTF-8
UTF-8
- 21
- 21
+ 24
+ 24
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index 15d272b8..f39596ad 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -2,7 +2,6 @@
import org.jooq.DSLContext;
import org.papertrail.utilities.MessageEncryption;
-import org.tinylog.Logger;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
@@ -26,11 +25,7 @@ public void logMessage(String messageId, String messageContent, String authorId)
.columns(field(MESSAGE_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN), field(AUTHOR_ID_COLUMN))
.values(Long.parseLong(messageId), MessageEncryption.encrypt(messageContent), Long.parseLong(authorId))
.onConflictDoNothing()
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error logging message to the database. MessageID: {} AuthorID: {}",messageId, authorId);
- return null;
- });
+ .execute();
}
public AuthorAndMessageEntity retrieveAuthorAndMessage (String messageId) {
@@ -54,21 +49,13 @@ public void updateMessage (String messageId, String messageContent) {
dsl.update(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.set(field(MESSAGE_CONTENT_COLUMN), MessageEncryption.encrypt(messageContent))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error updating message in the database. MessageID: "+messageId);
- return null;
- });
+ .execute();
}
public void deleteMessage (String messageId) {
dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error deleting message from database. MessageID: "+messageId);
- return null;
- });
+ .execute();
}
}
From c9ed792d6c952498166b113b96ba95f3585b20e5 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 12:54:44 +0530
Subject: [PATCH 08/16] Revert "Update to JDK 24 and switch to synchronous DB
operations"
This reverts commit 544095d4e50e3563d5131976ad7da7489c512617.
---
Dockerfile | 6 +++---
pom.xml | 4 ++--
.../database/MessageDataAccess.java | 19 ++++++++++++++++---
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 1b7b117f..f19c3903 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Importing JDK and copying required files
-FROM openjdk:24-jdk AS build
+FROM openjdk:21-jdk AS build
WORKDIR /app
# Copy Maven wrapper
@@ -16,8 +16,8 @@ COPY src ./src
RUN ./mvnw clean package -DskipTests
-# Stage 2: Create the final Docker image using OpenJDK 24
-FROM openjdk:24-jdk
+# Stage 2: Create the final Docker image using OpenJDK 21
+FROM openjdk:21-jdk
WORKDIR /app
VOLUME /tmp
diff --git a/pom.xml b/pom.xml
index 2cd1cf12..c8df87e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
UTF-8
UTF-8
- 24
- 24
+ 21
+ 21
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index f39596ad..15d272b8 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -2,6 +2,7 @@
import org.jooq.DSLContext;
import org.papertrail.utilities.MessageEncryption;
+import org.tinylog.Logger;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
@@ -25,7 +26,11 @@ public void logMessage(String messageId, String messageContent, String authorId)
.columns(field(MESSAGE_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN), field(AUTHOR_ID_COLUMN))
.values(Long.parseLong(messageId), MessageEncryption.encrypt(messageContent), Long.parseLong(authorId))
.onConflictDoNothing()
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error logging message to the database. MessageID: {} AuthorID: {}",messageId, authorId);
+ return null;
+ });
}
public AuthorAndMessageEntity retrieveAuthorAndMessage (String messageId) {
@@ -49,13 +54,21 @@ public void updateMessage (String messageId, String messageContent) {
dsl.update(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.set(field(MESSAGE_CONTENT_COLUMN), MessageEncryption.encrypt(messageContent))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error updating message in the database. MessageID: "+messageId);
+ return null;
+ });
}
public void deleteMessage (String messageId) {
dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .execute();
+ .executeAsync()
+ .exceptionally(e -> {
+ Logger.error(e, "Error deleting message from database. MessageID: "+messageId);
+ return null;
+ });
}
}
From 153037ce924f5c8e5c1b535b14fec764cd0e7e86 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 13:08:31 +0530
Subject: [PATCH 09/16] Refactor message logging to use synchronous DB ops
Replaces asynchronous database operations with synchronous calls in MessageDataAccess, removing Tinylog error handling. In MessageLogListener, introduces a virtual thread pool to offload database operations and removes try-catch blocks and logging
---
.../database/MessageDataAccess.java | 19 +----
.../messagelisteners/MessageLogListener.java | 85 +++++++++----------
2 files changed, 43 insertions(+), 61 deletions(-)
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index 15d272b8..f39596ad 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -2,7 +2,6 @@
import org.jooq.DSLContext;
import org.papertrail.utilities.MessageEncryption;
-import org.tinylog.Logger;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
@@ -26,11 +25,7 @@ public void logMessage(String messageId, String messageContent, String authorId)
.columns(field(MESSAGE_ID_COLUMN), field(MESSAGE_CONTENT_COLUMN), field(AUTHOR_ID_COLUMN))
.values(Long.parseLong(messageId), MessageEncryption.encrypt(messageContent), Long.parseLong(authorId))
.onConflictDoNothing()
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error logging message to the database. MessageID: {} AuthorID: {}",messageId, authorId);
- return null;
- });
+ .execute();
}
public AuthorAndMessageEntity retrieveAuthorAndMessage (String messageId) {
@@ -54,21 +49,13 @@ public void updateMessage (String messageId, String messageContent) {
dsl.update(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.set(field(MESSAGE_CONTENT_COLUMN), MessageEncryption.encrypt(messageContent))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error updating message in the database. MessageID: "+messageId);
- return null;
- });
+ .execute();
}
public void deleteMessage (String messageId) {
dsl.deleteFrom(table(TableNames.MESSAGE_LOG_CONTENT_TABLE))
.where(field(MESSAGE_ID_COLUMN).eq(Long.parseLong(messageId)))
- .executeAsync()
- .exceptionally(e -> {
- Logger.error(e, "Error deleting message from database. MessageID: "+messageId);
- return null;
- });
+ .execute();
}
}
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
index 577198e0..dd49c13c 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
@@ -2,10 +2,13 @@
import java.awt.Color;
import java.time.Instant;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
import org.papertrail.database.AuthorAndMessageEntity;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
-import org.tinylog.Logger;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
@@ -16,8 +19,10 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class MessageLogListener extends ListenerAdapter {
-
- private DatabaseConnector dc;
+
+ private final Executor vThreadPool = Executors.newVirtualThreadPerTaskExecutor();
+
+ private final DatabaseConnector dc;
public MessageLogListener(DatabaseConnector dc) {
this.dc = dc;
@@ -25,7 +30,7 @@ public MessageLogListener(DatabaseConnector dc) {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
-
+
// if the author is a bot or system, don't log
if(event.getAuthor().isBot() || event.getAuthor().isSystem()) {
return;
@@ -34,23 +39,22 @@ public void onMessageReceived(MessageReceivedEvent event) {
if(event.getMessage().getContentRaw().isEmpty()) {
return;
}
-
+
// get the guild id for which the event was fired
String guildId = event.getGuild().getId();
// see if the guild id is registered in the database for logging
-
+
// if not registered, exit
if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) {
return;
}
-
+
// else if the registered guild id matches with the event fetched guild id, log the message with its ID and author
- try {
- String messageId = event.getMessageId();
- dc.getMessageDataAccess().logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId());
- } catch (Exception e) {
- Logger.error(e, "Could not log message");
- }
+ vThreadPool.execute(()->
+ dc.getMessageDataAccess().logMessage(event.getMessageId(), event.getMessage().getContentRaw(), event.getAuthor().getId())
+ );
+
+
}
@Override
@@ -60,56 +64,51 @@ public void onMessageUpdate(MessageUpdateEvent event) {
return;
}
-
String guildId = event.getGuild().getId();
-
if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) {
return;
}
- try {
+ vThreadPool.execute(()->{
// get the message id of the message which was updated
String messageId = event.getMessageId();
-
+
// fetch the old message content and its author from the database
AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
if(ame==null || ame.getAuthorId()==null || ame.getAuthorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
return;
}
- // fetch the updated message and its author from the event
- String updatedMessage = event.getMessage().getContentRaw();
-
+ // fetch the updated message and its author from the event
+ String updatedMessage = event.getMessage().getContentRaw();
+
// Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
// This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
if(updatedMessage.equals(ame.getMessageContent())) {
return;
}
-
+
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("π Message Edit Event");
eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
eb.setColor(Color.YELLOW);
-
+
eb.addField("Old Message", ame.getMessageContent(), false); // get only the message and not the author
eb.addField("New Message", updatedMessage, false);
-
+
eb.setFooter(event.getGuild().getName());
eb.setTimestamp(Instant.now());
// update the database with the new message
dc.getMessageDataAccess().updateMessage(messageId, updatedMessage);
// the reason this is above the send queue is because in case where the user did not give sufficient permissions to
- // the bot, the error responses wouldn't block the update of the message in the database.
-
+ // the bot, the error responses wouldn't block the update of the message in the database.
+
// fetch the channel id from the database
// this channel is where the logs will be sent to
// wrap the embed and send
MessageEmbed mb = eb.build();
String channelIdToSendTo = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
- } catch (Exception e) {
- Logger.error(e, "Could not log updated message");
-
- }
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ });
}
@Override
@@ -121,44 +120,40 @@ public void onMessageDelete(MessageDeleteEvent event) {
return;
}
- try {
+ vThreadPool.execute(()-> {
// get the message id of the message which was deleted
String messageId = event.getMessageId();
-
+
// if the message id does not exist in db, it means the message has not been logged in the first place
if(!dc.getMessageDataAccess().messageExists(messageId)) {
return;
}
-
+
// retrieve the channel id where the logs must be sent
String channelIdToSendTo = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
// retrieve the stored message in the database which was deleted
AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
-
+
User author = event.getJDA().getUserById(ame.getAuthorId());
String mentionableAuthor = (author !=null ? author.getAsMention() : ame.getAuthorId());
-
+
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("ποΈ Message Delete Event");
eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
eb.setColor(Color.RED);
eb.addField("Deleted Message", ame.getMessageContent(), false);
-
+
eb.setFooter(event.getGuild().getName());
eb.setTimestamp(Instant.now());
-
- // delete the message from the database
+
+ // delete the message from the database
dc.getMessageDataAccess().deleteMessage(messageId);
// the reason this is above the send queue is because in case where the user did not give sufficient permissions to
// the bot, (such as no send message permissions) the exceptions wouldn't block the deletion in the database.
-
+
// send the fetched deleted message to the logging channel
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
-
- } catch (Exception e) {
- Logger.error(e, "Could not delete message");
-
- }
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ });
}
}
From 4dfe13c2348ac9a2f9dbbfe179631f1310331282 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 13:23:53 +0530
Subject: [PATCH 10/16] Refactor listener package structure and imports
Moved and renamed several listener classes to better organize them under 'commandlisteners' and 'loglisteners' packages. Updated package-info files and adjusted all relevant imports in FireRun.java to reflect the new structure. This improves code organization and clarity by grouping listeners according to their responsibilities.
---
.../AnnouncementCommandListener.java} | 6 +--
.../AuditLogSetupCommandListener.java} | 6 +--
.../BotInfoCommandListener.java} | 4 +-
.../BotSetupCommandListener.java} | 4 +-
.../MessageLogSetupCommandListener.java} | 6 +--
...quiredPermissionCheckCommandListener.java} | 4 +-
.../ServerStatCommandListener.java} | 4 +-
.../commandlisteners/package-info.java | 4 ++
.../customlisteners/package-info.java | 4 --
.../MessageLogListener.java | 2 +-
.../listeners/loglisteners/package-info.java | 2 +-
.../messagelisteners/package-info.java | 4 --
.../java/org/papertrail/main/FireRun.java | 49 ++++++++++---------
13 files changed, 50 insertions(+), 49 deletions(-)
rename src/main/java/org/papertrail/listeners/{customlisteners/AnnouncementListener.java => commandlisteners/AnnouncementCommandListener.java} (93%)
rename src/main/java/org/papertrail/listeners/{loglisteners/AuditLogCommandListener.java => commandlisteners/AuditLogSetupCommandListener.java} (97%)
rename src/main/java/org/papertrail/listeners/{customlisteners/BotInfoListener.java => commandlisteners/BotInfoCommandListener.java} (92%)
rename src/main/java/org/papertrail/listeners/{customlisteners/BotSetupListener.java => commandlisteners/BotSetupCommandListener.java} (96%)
rename src/main/java/org/papertrail/listeners/{messagelisteners/MessageLogCommandListener.java => commandlisteners/MessageLogSetupCommandListener.java} (97%)
rename src/main/java/org/papertrail/listeners/{customlisteners/RequiredPermissionCheckListener.java => commandlisteners/RequiredPermissionCheckCommandListener.java} (95%)
rename src/main/java/org/papertrail/listeners/{customlisteners/ServerStatListener.java => commandlisteners/ServerStatCommandListener.java} (96%)
create mode 100644 src/main/java/org/papertrail/listeners/commandlisteners/package-info.java
delete mode 100644 src/main/java/org/papertrail/listeners/customlisteners/package-info.java
rename src/main/java/org/papertrail/listeners/{messagelisteners => loglisteners}/MessageLogListener.java (99%)
delete mode 100644 src/main/java/org/papertrail/listeners/messagelisteners/package-info.java
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
similarity index 93%
rename from src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
index 019a2eeb..6b1e6694 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.customlisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
import java.time.Instant;
@@ -17,11 +17,11 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
-public class AnnouncementListener extends ListenerAdapter {
+public class AnnouncementCommandListener extends ListenerAdapter {
private final DatabaseConnector dc;
- public AnnouncementListener(DatabaseConnector dc) {
+ public AnnouncementCommandListener(DatabaseConnector dc) {
this.dc = dc;
}
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
similarity index 97%
rename from src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
index 6c456269..972ea2eb 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.loglisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
@@ -14,12 +14,12 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class AuditLogCommandListener extends ListenerAdapter {
+public class AuditLogSetupCommandListener extends ListenerAdapter {
private DatabaseConnector dc;
- public AuditLogCommandListener(DatabaseConnector dc) {
+ public AuditLogSetupCommandListener(DatabaseConnector dc) {
this.dc = dc;
}
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/BotInfoCommandListener.java
similarity index 92%
rename from src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/BotInfoCommandListener.java
index e5e2aaa2..0829a6e8 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/BotInfoCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.customlisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
import java.time.Instant;
@@ -11,7 +11,7 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class BotInfoListener extends ListenerAdapter {
+public class BotInfoCommandListener extends ListenerAdapter {
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/BotSetupCommandListener.java
similarity index 96%
rename from src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/BotSetupCommandListener.java
index 7a50786f..99226ae4 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/BotSetupCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.customlisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
import java.time.Instant;
@@ -10,7 +10,7 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class BotSetupListener extends ListenerAdapter {
+public class BotSetupCommandListener extends ListenerAdapter {
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
similarity index 97%
rename from src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
index 0a1bb461..8cd73f43 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.messagelisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
@@ -15,12 +15,12 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class MessageLogCommandListener extends ListenerAdapter {
+public class MessageLogSetupCommandListener extends ListenerAdapter {
private DatabaseConnector dc;
private final EmbedBuilder eb = new EmbedBuilder();
- public MessageLogCommandListener(DatabaseConnector dc) {
+ public MessageLogSetupCommandListener(DatabaseConnector dc) {
this.dc = dc;
eb.setTitle("π Message Log Configuration");
eb.setColor(Color.CYAN);
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/RequiredPermissionCheckListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
similarity index 95%
rename from src/main/java/org/papertrail/listeners/customlisteners/RequiredPermissionCheckListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
index 7b7c799e..a7a81a0c 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/RequiredPermissionCheckListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.customlisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
import java.util.EnumMap;
@@ -15,7 +15,7 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class RequiredPermissionCheckListener extends ListenerAdapter {
+public class RequiredPermissionCheckCommandListener extends ListenerAdapter {
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/ServerStatListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
similarity index 96%
rename from src/main/java/org/papertrail/listeners/customlisteners/ServerStatListener.java
rename to src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
index b8a1f5c3..5fb7c6fb 100644
--- a/src/main/java/org/papertrail/listeners/customlisteners/ServerStatListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.customlisteners;
+package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
import java.time.Instant;
@@ -14,7 +14,7 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-public class ServerStatListener extends ListenerAdapter{
+public class ServerStatCommandListener extends ListenerAdapter{
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/package-info.java b/src/main/java/org/papertrail/listeners/commandlisteners/package-info.java
new file mode 100644
index 00000000..dd37ae86
--- /dev/null
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * This package contains classes that listen for slash commands
+ */
+package org.papertrail.listeners.commandlisteners;
\ No newline at end of file
diff --git a/src/main/java/org/papertrail/listeners/customlisteners/package-info.java b/src/main/java/org/papertrail/listeners/customlisteners/package-info.java
deleted file mode 100644
index f650e385..00000000
--- a/src/main/java/org/papertrail/listeners/customlisteners/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
- * This will include Custom Listeners that may or may not depend on a specific or generic event
- */
-package org.papertrail.listeners.customlisteners;
\ No newline at end of file
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
similarity index 99%
rename from src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
rename to src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
index dd49c13c..4b0ba954 100644
--- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
@@ -1,4 +1,4 @@
-package org.papertrail.listeners.messagelisteners;
+package org.papertrail.listeners.loglisteners;
import java.awt.Color;
import java.time.Instant;
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/package-info.java b/src/main/java/org/papertrail/listeners/loglisteners/package-info.java
index b184ad6c..209ac0be 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/package-info.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/package-info.java
@@ -1,4 +1,4 @@
/**
- * This package contains Classes and Methods that detect and parse audit log activities
+ * This package contains Classes and Methods that detect and parse audit and message log activities
*/
package org.papertrail.listeners.loglisteners;
\ No newline at end of file
diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java b/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java
deleted file mode 100644
index ff3f1938..00000000
--- a/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
- * Groups listeners related to message activities
- */
-package org.papertrail.listeners.messagelisteners;
\ No newline at end of file
diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java
index e1e8d0a1..2f6d47d2 100644
--- a/src/main/java/org/papertrail/main/FireRun.java
+++ b/src/main/java/org/papertrail/main/FireRun.java
@@ -5,20 +5,21 @@
import java.security.Security;
import java.sql.SQLException;
+import net.dv8tion.jda.api.sharding.ShardManager;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.papertrail.cleanup.BotKickListener;
import org.papertrail.database.DatabaseConnector;
-import org.papertrail.listeners.customlisteners.AnnouncementListener;
-import org.papertrail.listeners.customlisteners.BotInfoListener;
-import org.papertrail.listeners.customlisteners.ServerStatListener;
-import org.papertrail.listeners.customlisteners.BotSetupListener;
-import org.papertrail.listeners.customlisteners.RequiredPermissionCheckListener;
+import org.papertrail.listeners.commandlisteners.AnnouncementCommandListener;
+import org.papertrail.listeners.commandlisteners.BotInfoCommandListener;
+import org.papertrail.listeners.commandlisteners.ServerStatCommandListener;
+import org.papertrail.listeners.commandlisteners.BotSetupCommandListener;
+import org.papertrail.listeners.commandlisteners.RequiredPermissionCheckCommandListener;
import org.papertrail.listeners.guildlisteners.ServerBoostListener;
import org.papertrail.listeners.loglisteners.AuditLogListener;
-import org.papertrail.listeners.loglisteners.AuditLogCommandListener;
+import org.papertrail.listeners.commandlisteners.AuditLogSetupCommandListener;
import org.papertrail.listeners.memberlisteners.GuildMemberJoinAndLeaveListener;
-import org.papertrail.listeners.messagelisteners.MessageLogCommandListener;
-import org.papertrail.listeners.messagelisteners.MessageLogListener;
+import org.papertrail.listeners.commandlisteners.MessageLogSetupCommandListener;
+import org.papertrail.listeners.loglisteners.MessageLogListener;
import org.papertrail.listeners.voicelisteners.GuildVoiceListener;
import org.tinylog.Logger;
@@ -47,20 +48,24 @@ public static void main(String[] args) throws IOException, SQLException {
DatabaseConnector dc = new DatabaseConnector();
ConnectionInitializer ci = new ConnectionInitializer();
- ci.getManager().addEventListener(new AuditLogCommandListener(dc));
- ci.getManager().addEventListener(new AuditLogListener(dc));
- ci.getManager().addEventListener(new GuildVoiceListener(dc));
- ci.getManager().addEventListener(new GuildMemberJoinAndLeaveListener(dc));
- ci.getManager().addEventListener(new ServerBoostListener(dc));
- ci.getManager().addEventListener(new BotKickListener(dc));
- ci.getManager().addEventListener(new MessageLogCommandListener(dc));
- ci.getManager().addEventListener(new MessageLogListener(dc));
-
- ci.getManager().addEventListener(new ServerStatListener());
- ci.getManager().addEventListener(new BotInfoListener());
- ci.getManager().addEventListener(new BotSetupListener());
- ci.getManager().addEventListener(new AnnouncementListener(dc));
- ci.getManager().addEventListener(new RequiredPermissionCheckListener());
+ ShardManager manager = ci.getManager();
+
+ manager.addEventListener(new AuditLogSetupCommandListener(dc));
+ manager.addEventListener(new AuditLogListener(dc));
+
+ manager.addEventListener(new MessageLogSetupCommandListener(dc));
+ manager.addEventListener(new MessageLogListener(dc));
+
+ manager.addEventListener(new GuildVoiceListener(dc));
+ manager.addEventListener(new GuildMemberJoinAndLeaveListener(dc));
+ manager.addEventListener(new ServerBoostListener(dc));
+ manager.addEventListener(new BotKickListener(dc));
+
+ manager.addEventListener(new ServerStatCommandListener());
+ manager.addEventListener(new BotInfoCommandListener());
+ manager.addEventListener(new BotSetupCommandListener());
+ manager.addEventListener(new AnnouncementCommandListener(dc));
+ manager.addEventListener(new RequiredPermissionCheckCommandListener());
/*
* This is required only to set up a cron-job to periodically ping this end-point so that
From 6a96688435e7a148cfd86d61b6bcb1c2a4a4400a Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 14:55:41 +0530
Subject: [PATCH 11/16] Refactor listeners to use shared virtual thread pool
All event listeners handling blocking I/O now accept an Executor for I/O operations, and FireRun provides a shared virtual thread pool to each listener. This improves concurrency and resource management by running blocking operations off the main thread. Minor TODO comments for logging were also added in data access classes.
---
.../papertrail/cleanup/BotKickListener.java | 20 +--
.../papertrail/database/GuildDataAccess.java | 3 +-
.../database/MessageDataAccess.java | 2 +-
.../guildlisteners/ServerBoostListener.java | 94 ++++++------
.../loglisteners/AuditLogListener.java | 26 ++--
.../loglisteners/MessageLogListener.java | 9 +-
.../GuildMemberJoinAndLeaveListener.java | 135 ++++++++++--------
.../voicelisteners/GuildVoiceListener.java | 102 ++++++-------
.../java/org/papertrail/main/FireRun.java | 19 ++-
9 files changed, 222 insertions(+), 188 deletions(-)
diff --git a/src/main/java/org/papertrail/cleanup/BotKickListener.java b/src/main/java/org/papertrail/cleanup/BotKickListener.java
index 26ec55cd..ceba7f9e 100644
--- a/src/main/java/org/papertrail/cleanup/BotKickListener.java
+++ b/src/main/java/org/papertrail/cleanup/BotKickListener.java
@@ -3,32 +3,34 @@
import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
-import org.tinylog.Logger;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.events.guild.GuildLeaveEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import java.util.concurrent.Executor;
+
/*
* This class will have methods that unregister the log channels from the database after the bot has been kicked
*/
public class BotKickListener extends ListenerAdapter {
- private DatabaseConnector dc;
+ private final Executor vThreadPool;
+ private final DatabaseConnector dc;
- public BotKickListener(DatabaseConnector dc) {
+ public BotKickListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc = dc;
+ this.vThreadPool = vThreadPool;
}
@Override
public void onGuildLeave(@NotNull GuildLeaveEvent event) {
- try {
- Guild leftGuild = event.getGuild();
+
+ Guild leftGuild = event.getGuild();
+ vThreadPool.execute(()->{
dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.AUDIT_LOG_TABLE);
dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
- } catch (Exception e) {
- Logger.error(e, "Could not auto-unregister guild upon guild leave: " + event.getGuild().getId() + "/"
- + event.getGuild().getName());
- }
+ });
+
}
}
diff --git a/src/main/java/org/papertrail/database/GuildDataAccess.java b/src/main/java/org/papertrail/database/GuildDataAccess.java
index 62faa32e..f5ac1b8a 100644
--- a/src/main/java/org/papertrail/database/GuildDataAccess.java
+++ b/src/main/java/org/papertrail/database/GuildDataAccess.java
@@ -8,8 +8,9 @@
import static org.jooq.impl.DSL.selectOne;
import static org.jooq.impl.DSL.table;
+// TODO Add logging
public class GuildDataAccess {
-
+
private final DSLContext dsl;
private static final String GUILD_ID_COLUMN = "guild_id";
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index f39596ad..4f4001dc 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -6,7 +6,7 @@
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
import static org.jooq.impl.DSL.table;
-
+// TODO Add Logging
public class MessageDataAccess {
private final DSLContext dsl;
diff --git a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
index 3bcc4064..8277be7b 100644
--- a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
+++ b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
@@ -3,7 +3,10 @@
import java.awt.Color;
import java.time.Instant;
import java.time.OffsetDateTime;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -15,55 +18,58 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class ServerBoostListener extends ListenerAdapter {
-
- private DatabaseConnector dc;
- public ServerBoostListener(DatabaseConnector dc) {
+ private final Executor vThreadPool;
+ private final DatabaseConnector dc;
+
+ public ServerBoostListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc=dc;
+ this.vThreadPool = vThreadPool;
}
@Override
- public void onGuildMemberUpdateBoostTime(GuildMemberUpdateBoostTimeEvent event) {
-
- // this will return a non-null text id if a channel was previously registered in the database
- // server boost logs are mapped to audit log table
- String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ public void onGuildMemberUpdateBoostTime(@NotNull GuildMemberUpdateBoostTimeEvent event) {
- if(registeredChannelId==null ||registeredChannelId.isBlank()) {
- return;
- }
-
- Member member = event.getMember();
- Guild guild = event.getGuild();
-
- String mentionableMember = (member!=null ? member.getAsMention() : "Unknown Member");
-
- OffsetDateTime newBoostTime = event.getNewTimeBoosted(); // Will be null if the member stopped boosting
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π Server Boost Event ");
- eb.setThumbnail(guild.getIconUrl());
-
- if (newBoostTime != null) {
- eb.setDescription("π **" + guild.getName() + "** has been boosted!");
- eb.setColor(Color.PINK);
- eb.addField("π Booster Gained", "β°ββ€"+mentionableMember+" has started boosting your server", false);
- eb.addField("π Total Boosts In The Server", "β°ββ€"+guild.getBoostCount(), false);
- eb.addField("ποΈ Current Boost Tier", "β°ββ€"+guild.getBoostTier().toString(), false);
- } else {
- eb.setDescription("β οΈ **" + guild.getName() + "** has lost a boost.");
- eb.setColor(Color.GRAY);
- eb.addField("πͺ« Booster Lost", "β°ββ€"+mentionableMember+" has removed their boost from your server", false);
- eb.addField("π Remaining Boosts In The Server", "β°ββ€"+guild.getBoostCount(), false);
- eb.addField("ποΈ Current Boost Tier", "β°ββ€"+guild.getBoostTier().toString(), false);
- eb.addField("Notice", "Boosts remain active for a period even after a member stops boosting, so the server's boost count doesn't update immediately.", false);
- }
-
- eb.setFooter("Server Boost Detection");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
- }
+ vThreadPool.execute(()->{
+ // this will return a non-null text id if a channel was previously registered in the database
+ // server boost logs are mapped to audit log table
+ String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+
+ if(registeredChannelId==null ||registeredChannelId.isBlank()) {
+ return;
+ }
+
+ Member member = event.getMember();
+ Guild guild = event.getGuild();
+
+ String mentionableMember = member.getAsMention();
+ OffsetDateTime newBoostTime = event.getNewTimeBoosted(); // Will be null if the member stopped boosting
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("π Server Boost Event ");
+ eb.setThumbnail(guild.getIconUrl());
+
+ if (newBoostTime != null) {
+ eb.setDescription("π **" + guild.getName() + "** has been boosted!");
+ eb.setColor(Color.PINK);
+ eb.addField("π Booster Gained", "β°ββ€"+mentionableMember+" has started boosting your server", false);
+ eb.addField("π Total Boosts In The Server", "β°ββ€"+guild.getBoostCount(), false);
+ eb.addField("ποΈ Current Boost Tier", "β°ββ€"+ guild.getBoostTier(), false);
+ } else {
+ eb.setDescription("β οΈ **" + guild.getName() + "** has lost a boost.");
+ eb.setColor(Color.GRAY);
+ eb.addField("πͺ« Booster Lost", "β°ββ€"+mentionableMember+" has removed their boost from your server", false);
+ eb.addField("π Remaining Boosts In The Server", "β°ββ€"+guild.getBoostCount(), false);
+ eb.addField("ποΈ Current Boost Tier", "β°ββ€"+ guild.getBoostTier(), false);
+ eb.addField("Notice", "Boosts remain active for a period even after a member stops boosting, so the server's boost count doesn't update immediately.", false);
+ }
+
+ eb.setFooter("Server Boost Detection");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ });
+ }
}
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
index 2d88f199..edf4a829 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
@@ -5,8 +5,10 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Executor;
import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
import org.papertrail.utilities.ColorFormatter;
@@ -35,24 +37,28 @@
public class AuditLogListener extends ListenerAdapter{
- private DatabaseConnector dc;
+ private final Executor vThreadPool;
+ private final DatabaseConnector dc;
- public AuditLogListener(DatabaseConnector dc) {
+ public AuditLogListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc=dc;
+ this.vThreadPool = vThreadPool;
}
@Override
- public void onGuildAuditLogEntryCreate(GuildAuditLogEntryCreateEvent event) {
+ public void onGuildAuditLogEntryCreate(@NotNull GuildAuditLogEntryCreateEvent event) {
- // this will return a non-null text id if a channel was previously registered in the database
- String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+ vThreadPool.execute(()->{
+ // this will return a non-null text id if a channel was previously registered in the database
+ String registeredChannelId=dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
- if(registeredChannelId==null ||registeredChannelId.isBlank()) {
- return;
- }
+ if(registeredChannelId==null ||registeredChannelId.isBlank()) {
+ return;
+ }
- AuditLogEntry ale = event.getEntry();
- auditLogParser(event, ale, registeredChannelId);
+ AuditLogEntry ale = event.getEntry();
+ auditLogParser(event, ale, registeredChannelId);
+ });
}
private void auditLogParser(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
index 4b0ba954..ef1a93a1 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
@@ -4,7 +4,6 @@
import java.time.Instant;
import java.util.Objects;
import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
import org.papertrail.database.AuthorAndMessageEntity;
import org.papertrail.database.DatabaseConnector;
@@ -20,12 +19,12 @@
public class MessageLogListener extends ListenerAdapter {
- private final Executor vThreadPool = Executors.newVirtualThreadPerTaskExecutor();
-
private final DatabaseConnector dc;
- public MessageLogListener(DatabaseConnector dc) {
+ private final Executor vThreadPool;
+
+ public MessageLogListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc = dc;
-
+ this.vThreadPool = vThreadPool;
}
@Override
diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
index 9f243992..27be2c82 100644
--- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
+++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
@@ -2,7 +2,9 @@
import java.awt.Color;
import java.time.Instant;
+import java.util.concurrent.Executor;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
import org.papertrail.utilities.DurationFormatter;
@@ -16,75 +18,82 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class GuildMemberJoinAndLeaveListener extends ListenerAdapter {
-
- private DatabaseConnector dc;
- public GuildMemberJoinAndLeaveListener (DatabaseConnector dc) {
+ private final Executor vThreadPool;
+ private final DatabaseConnector dc;
+
+ public GuildMemberJoinAndLeaveListener (DatabaseConnector dc, Executor vThreadPool) {
this.dc=dc;
+ this.vThreadPool = vThreadPool;
}
@Override
- public void onGuildMemberJoin(GuildMemberJoinEvent event) {
-
- // this will return a non-null text id if a channel was previously registered in
- // the database
- // guild member join and leave events are mapped to audit log table
- String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
-
- if (registeredChannelId == null || registeredChannelId.isBlank()) {
- return;
- }
-
- Guild guild = event.getGuild();
- User user = event.getUser();
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π¬ Member Join Event");
- eb.setDescription("A Member has joined "+guild.getName());
- eb.setColor(Color.GREEN);
-
- eb.addField("π·οΈ Member Name", "β°ββ€"+user.getName(), false);
- eb.setThumbnail(user.getEffectiveAvatarUrl());
- eb.addField("βΉοΈ Member Mention", "β°ββ€"+user.getAsMention(), false);
- eb.addField("π Member ID", "β°ββ€"+user.getId(), false);
- eb.addField("π
Account Created", "β°ββ€"+DurationFormatter.isoToLocalTimeCounter(user.getTimeCreated()), false);
- eb.addField("π€ Is Application ?", "β°ββ€"+((Boolean.TRUE.equals(user.isBot())) ? "β
" : "β"), false);
- eb.setFooter("Member Join Detection");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
-
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
+
+ vThreadPool.execute(()->{
+ // this will return a non-null text id if a channel was previously registered in
+ // the database
+ // guild member join and leave events are mapped to audit log table
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+
+ if (registeredChannelId == null || registeredChannelId.isBlank()) {
+ return;
+ }
+
+ Guild guild = event.getGuild();
+ User user = event.getUser();
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("π¬ Member Join Event");
+ eb.setDescription("A Member has joined "+guild.getName());
+ eb.setColor(Color.GREEN);
+
+ eb.addField("π·οΈ Member Name", "β°ββ€"+user.getName(), false);
+ eb.setThumbnail(user.getEffectiveAvatarUrl());
+ eb.addField("βΉοΈ Member Mention", "β°ββ€"+user.getAsMention(), false);
+ eb.addField("π Member ID", "β°ββ€"+user.getId(), false);
+ eb.addField("π
Account Created", "β°ββ€"+DurationFormatter.isoToLocalTimeCounter(user.getTimeCreated()), false);
+ eb.addField("π€ Is Application ?", "β°ββ€"+((user.isBot()) ? "β
" : "β"), false);
+ eb.setFooter("Member Join Detection");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+
+ event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ });
}
-
+
@Override
- public void onGuildMemberRemove(GuildMemberRemoveEvent event) {
-
- // this will return a non-null text id if a channel was previously registered in
- // the database
- String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
-
- if (registeredChannelId == null || registeredChannelId.isBlank()) {
- return;
- }
-
- Guild guild = event.getGuild();
- User user = event.getUser();
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π« Member Leave Event");
- eb.setDescription("A Member has left "+guild.getName());
- eb.setColor(Color.RED);
-
- eb.addField("π·οΈ Member Name", "β°ββ€"+user.getName(), false);
- eb.setThumbnail(user.getEffectiveAvatarUrl());
- eb.addField("π Member ID", "β°ββ€"+user.getId(), false);
-
- eb.setFooter("Member Leave Detection");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
-
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
+
+ vThreadPool.execute(() -> {
+ // this will return a non-null text id if a channel was previously registered in
+ // the database
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+
+ if (registeredChannelId == null || registeredChannelId.isBlank()) {
+ return;
+ }
+
+ Guild guild = event.getGuild();
+ User user = event.getUser();
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("π« Member Leave Event");
+ eb.setDescription("A Member has left "+guild.getName());
+ eb.setColor(Color.RED);
+
+ eb.addField("π·οΈ Member Name", "β°ββ€"+user.getName(), false);
+ eb.setThumbnail(user.getEffectiveAvatarUrl());
+ eb.addField("π Member ID", "β°ββ€"+user.getId(), false);
+
+ eb.setFooter("Member Leave Detection");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+
+ event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ });
}
+
}
diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
index b63268f1..ef3d2582 100644
--- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
+++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
@@ -2,7 +2,9 @@
import java.awt.Color;
import java.time.Instant;
+import java.util.concurrent.Executor;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -14,58 +16,62 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class GuildVoiceListener extends ListenerAdapter {
-
- private DatabaseConnector dc;
- public GuildVoiceListener(DatabaseConnector dc) {
+ private final Executor vThreadPool;
+ private final DatabaseConnector dc;
+
+ public GuildVoiceListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc=dc;
+ this.vThreadPool = vThreadPool;
}
@Override
- public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) {
-
- // this will return a non-null text id if a channel was previously registered in
- // the database
- // guild voice events are mapped to audit log table
- String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
-
- if (registeredChannelId == null || registeredChannelId.isBlank()) {
- return;
- }
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π Voice Activity Log");
-
- Member member = event.getMember();
- AudioChannel left = event.getOldValue(); // can be null if user joined for first time
- AudioChannel joined = event.getNewValue(); // can be null if user left
-
- if(left==null && joined!=null) {
- // User has joined a vc
- eb.setDescription("A Member has joined a voice channel");
- eb.setColor(Color.GREEN);
- eb.addField("β
Member Joined", "β°ββ€"+member.getAsMention()+" joined the voice channel "+joined.getAsMention(), false);
- }
-
- if (left != null && joined != null) {
- // Moved from one channel to another
- eb.setDescription("A Member has switched voice channels");
- eb.setColor(Color.YELLOW);
- eb.addField("π Member Switched Channels", "β°ββ€"+member.getAsMention()+" joined the switched from channel "+left.getAsMention()+ " to "+joined.getAsMention(), false);
- }
-
- if (left!=null && joined==null) {
- // User disconnected voluntarily (or was disconnected by a moderator)
- eb.setDescription("A Member has left a voice channel");
- eb.setColor(Color.RED);
- eb.addField("β Member Left A Voice Channel", "β°ββ€"+member.getAsMention()+" left the voice channel "+left.getAsMention(), false);
- }
-
- eb.setFooter("Voice Activity Detection");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
-
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) {
+
+ vThreadPool.execute(()->{
+ // this will return a non-null text id if a channel was previously registered in
+ // the database
+ // guild voice events are mapped to audit log table
+ String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE);
+
+ if (registeredChannelId == null || registeredChannelId.isBlank()) {
+ return;
+ }
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("π Voice Activity Log");
+
+ Member member = event.getMember();
+ AudioChannel left = event.getOldValue(); // can be null if user joined for first time
+ AudioChannel joined = event.getNewValue(); // can be null if user left
+
+ if(left==null && joined!=null) {
+ // User has joined a vc
+ eb.setDescription("A Member has joined a voice channel");
+ eb.setColor(Color.GREEN);
+ eb.addField("β
Member Joined", "β°ββ€"+member.getAsMention()+" joined the voice channel "+joined.getAsMention(), false);
+ }
+
+ if (left != null && joined != null) {
+ // Moved from one channel to another
+ eb.setDescription("A Member has switched voice channels");
+ eb.setColor(Color.YELLOW);
+ eb.addField("π Member Switched Channels", "β°ββ€"+member.getAsMention()+" joined the switched from channel "+left.getAsMention()+ " to "+joined.getAsMention(), false);
+ }
+
+ if (left!=null && joined==null) {
+ // User disconnected voluntarily (or was disconnected by a moderator)
+ eb.setDescription("A Member has left a voice channel");
+ eb.setColor(Color.RED);
+ eb.addField("β Member Left A Voice Channel", "β°ββ€"+member.getAsMention()+" left the voice channel "+left.getAsMention(), false);
+ }
+
+ eb.setFooter("Voice Activity Detection");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+
+ event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ });
}
}
diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java
index 2f6d47d2..5def22d4 100644
--- a/src/main/java/org/papertrail/main/FireRun.java
+++ b/src/main/java/org/papertrail/main/FireRun.java
@@ -4,6 +4,8 @@
import java.net.InetSocketAddress;
import java.security.Security;
import java.sql.SQLException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import net.dv8tion.jda.api.sharding.ShardManager;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -30,7 +32,10 @@
* The main class of the bot
*/
public class FireRun {
-
+
+ // All I/O blocking operations run inside the vThreadPool
+ private static final Executor vThreadPool = Executors.newVirtualThreadPerTaskExecutor();
+
// Register Bouncy Castle as a security provider
// Required for the PBEWITHSHA256AND256BITAES-CBC-BC encryption algorithm
private static void registerBouncyCastle() {
@@ -51,15 +56,15 @@ public static void main(String[] args) throws IOException, SQLException {
ShardManager manager = ci.getManager();
manager.addEventListener(new AuditLogSetupCommandListener(dc));
- manager.addEventListener(new AuditLogListener(dc));
+ manager.addEventListener(new AuditLogListener(dc, vThreadPool));
manager.addEventListener(new MessageLogSetupCommandListener(dc));
- manager.addEventListener(new MessageLogListener(dc));
+ manager.addEventListener(new MessageLogListener(dc, vThreadPool));
- manager.addEventListener(new GuildVoiceListener(dc));
- manager.addEventListener(new GuildMemberJoinAndLeaveListener(dc));
- manager.addEventListener(new ServerBoostListener(dc));
- manager.addEventListener(new BotKickListener(dc));
+ manager.addEventListener(new GuildVoiceListener(dc, vThreadPool));
+ manager.addEventListener(new GuildMemberJoinAndLeaveListener(dc, vThreadPool));
+ manager.addEventListener(new ServerBoostListener(dc, vThreadPool));
+ manager.addEventListener(new BotKickListener(dc, vThreadPool));
manager.addEventListener(new ServerStatCommandListener());
manager.addEventListener(new BotInfoCommandListener());
From e0ef5ee835c749dacb345edac1466bb86c050d9a Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Fri, 18 Jul 2025 18:14:12 +0530
Subject: [PATCH 12/16] Add per-message locking to MessageLogListener
Introduces Guava's Striped locks and an AtomicLong to ensure thread-safe operations on messages in MessageLogListener. Database operations for logging, updating, and deleting messages are now wrapped in a lock per message ID to prevent race conditions. Guava dependency added to pom.xml.
---
pom.xml | 7 ++++-
.../loglisteners/MessageLogListener.java | 29 +++++++++++++++----
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index c8df87e9..b6667fe1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,7 +67,12 @@
org.bouncycastle
bcprov-jdk18on
1.81
-
+
+
+ com.google.guava
+ guava
+ 33.4.8-jre
+
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
index ef1a93a1..2e2114f4 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
@@ -4,7 +4,10 @@
import java.time.Instant;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
+import com.google.common.util.concurrent.Striped;
import org.papertrail.database.AuthorAndMessageEntity;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -16,16 +19,31 @@
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import org.tinylog.Logger;
public class MessageLogListener extends ListenerAdapter {
private final DatabaseConnector dc;
private final Executor vThreadPool;
+ private final Striped messageLocks = Striped.lock(8192);
+ private final AtomicLong activeLockCount = new AtomicLong(0);
public MessageLogListener(DatabaseConnector dc, Executor vThreadPool) {
this.dc = dc;
this.vThreadPool = vThreadPool;
}
+
+ private void withMessageLock (String messageId, Runnable task) {
+ Lock lock = messageLocks.get(messageId);
+ lock.lock();
+ Logger.info("Lock acquired for message id: {} . Active lock count: {}", messageId, activeLockCount.incrementAndGet());
+ try{
+ task.run();
+ } finally {
+ lock.unlock();
+ Logger.info("Lock released for message id: {} . Active lock count: {}", messageId, activeLockCount.decrementAndGet());
+ }
+ }
@Override
public void onMessageReceived(MessageReceivedEvent event) {
@@ -49,9 +67,10 @@ public void onMessageReceived(MessageReceivedEvent event) {
}
// else if the registered guild id matches with the event fetched guild id, log the message with its ID and author
- vThreadPool.execute(()->
- dc.getMessageDataAccess().logMessage(event.getMessageId(), event.getMessage().getContentRaw(), event.getAuthor().getId())
- );
+ vThreadPool.execute(()-> {
+ String messageId = event.getMessageId();
+ withMessageLock(messageId, ()-> dc.getMessageDataAccess().logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId()));
+ });
}
@@ -97,7 +116,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
eb.setFooter(event.getGuild().getName());
eb.setTimestamp(Instant.now());
// update the database with the new message
- dc.getMessageDataAccess().updateMessage(messageId, updatedMessage);
+ withMessageLock(messageId, ()->dc.getMessageDataAccess().updateMessage(messageId, updatedMessage));
// the reason this is above the send queue is because in case where the user did not give sufficient permissions to
// the bot, the error responses wouldn't block the update of the message in the database.
@@ -146,7 +165,7 @@ public void onMessageDelete(MessageDeleteEvent event) {
eb.setTimestamp(Instant.now());
// delete the message from the database
- dc.getMessageDataAccess().deleteMessage(messageId);
+ withMessageLock(messageId, ()->dc.getMessageDataAccess().deleteMessage(messageId));
// the reason this is above the send queue is because in case where the user did not give sufficient permissions to
// the bot, (such as no send message permissions) the exceptions wouldn't block the deletion in the database.
From f37088601a309b7090d862b0a0d688f33e82fe43 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Sun, 20 Jul 2025 09:32:08 +0530
Subject: [PATCH 13/16] Make key fields final and fix bitmask map keys
Marked key fields as final in several listener classes to ensure immutability. Simplified the bitmask map keys in GuildSystemChannelFlagResolver and PermissionResolver by replacing '1L << 0' with '1L'.
---
.../commandlisteners/AuditLogSetupCommandListener.java | 2 +-
.../commandlisteners/MessageLogSetupCommandListener.java | 2 +-
src/main/java/org/papertrail/main/ActivityUpdateListener.java | 2 +-
.../papertrail/utilities/GuildSystemChannelFlagResolver.java | 2 +-
src/main/java/org/papertrail/utilities/PermissionResolver.java | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
index 972ea2eb..725c2e6d 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
@@ -16,7 +16,7 @@
public class AuditLogSetupCommandListener extends ListenerAdapter {
- private DatabaseConnector dc;
+ private final DatabaseConnector dc;
public AuditLogSetupCommandListener(DatabaseConnector dc) {
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
index 8cd73f43..f46e3047 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
@@ -17,7 +17,7 @@
public class MessageLogSetupCommandListener extends ListenerAdapter {
- private DatabaseConnector dc;
+ private final DatabaseConnector dc;
private final EmbedBuilder eb = new EmbedBuilder();
public MessageLogSetupCommandListener(DatabaseConnector dc) {
diff --git a/src/main/java/org/papertrail/main/ActivityUpdateListener.java b/src/main/java/org/papertrail/main/ActivityUpdateListener.java
index 74054915..f69b6d47 100644
--- a/src/main/java/org/papertrail/main/ActivityUpdateListener.java
+++ b/src/main/java/org/papertrail/main/ActivityUpdateListener.java
@@ -14,7 +14,7 @@
*/
public class ActivityUpdateListener extends ListenerAdapter {
- private ShardManager manager;
+ private final ShardManager manager;
public ActivityUpdateListener(ShardManager manager) {
this.manager = manager;
diff --git a/src/main/java/org/papertrail/utilities/GuildSystemChannelFlagResolver.java b/src/main/java/org/papertrail/utilities/GuildSystemChannelFlagResolver.java
index 46150e56..f79862fd 100644
--- a/src/main/java/org/papertrail/utilities/GuildSystemChannelFlagResolver.java
+++ b/src/main/java/org/papertrail/utilities/GuildSystemChannelFlagResolver.java
@@ -5,7 +5,7 @@
public class GuildSystemChannelFlagResolver {
private static final Map SYSTEM_CHANNEL_FLAG_MAP = Map.ofEntries(
- Map.entry(1L << 0, "Suppress member join notifications"),
+ Map.entry(1L, "Suppress member join notifications"),
Map.entry(1L << 1, "Suppress server boost notifications"),
Map.entry(1L << 2, "Suppress server setup tips"),
Map.entry(1L << 3, "Hide member join sticker reply buttons"),
diff --git a/src/main/java/org/papertrail/utilities/PermissionResolver.java b/src/main/java/org/papertrail/utilities/PermissionResolver.java
index 457e1635..0481a989 100644
--- a/src/main/java/org/papertrail/utilities/PermissionResolver.java
+++ b/src/main/java/org/papertrail/utilities/PermissionResolver.java
@@ -5,7 +5,7 @@
public class PermissionResolver {
private static final Map PERMISSION_MAP = Map.ofEntries(
- Map.entry(1L << 0, "CREATE_INSTANT_INVITE"),
+ Map.entry(1L, "CREATE_INSTANT_INVITE"),
Map.entry(1L << 1, "KICK_MEMBERS"),
Map.entry(1L << 2, "BAN_MEMBERS"),
Map.entry(1L << 3, "ADMINISTRATOR"),
From a58bf3ace0e8a032667946b44a4455674a291dcd Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Sun, 20 Jul 2025 10:05:20 +0530
Subject: [PATCH 14/16] Add null safety and refactor for modern Java features
Replaces custom POJO with Java record for AuthorAndMessageEntity, adds Objects.requireNonNull assertions throughout listeners for improved null safety, and updates integer parsing to use primitive int in TypeResolver. Also removes unnecessary SQLException handling in main and database connector constructors, and applies minor code cleanups and assertion checks for better reliability and readability.
---
.../database/AuthorAndMessageEntity.java | 20 +--
.../database/DatabaseConnector.java | 4 +-
.../AnnouncementCommandListener.java | 9 +-
.../AuditLogSetupCommandListener.java | 7 +-
.../MessageLogSetupCommandListener.java | 7 +-
...equiredPermissionCheckCommandListener.java | 16 +-
.../ServerStatCommandListener.java | 18 ++-
.../loglisteners/AuditLogListener.java | 143 +++++++++---------
.../loglisteners/MessageLogListener.java | 12 +-
.../GuildMemberJoinAndLeaveListener.java | 5 +-
.../voicelisteners/GuildVoiceListener.java | 3 +-
.../java/org/papertrail/main/FireRun.java | 3 +-
.../papertrail/utilities/TypeResolver.java | 8 +-
13 files changed, 122 insertions(+), 133 deletions(-)
diff --git a/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java b/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
index 736c1085..98fe2dae 100644
--- a/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
+++ b/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java
@@ -1,22 +1,6 @@
package org.papertrail.database;
-public class AuthorAndMessageEntity {
-
- private final String authorId;
- private final String messageContent;
-
- public AuthorAndMessageEntity(String authorId, String messageContent) {
- super();
- this.authorId = authorId;
- this.messageContent = messageContent;
- }
-
- public String getAuthorId() {
- return authorId;
- }
+public record AuthorAndMessageEntity(String authorId, String messageContent) {
+
- public String getMessageContent() {
- return messageContent;
- }
-
}
diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java
index 577021ed..f8bb6468 100644
--- a/src/main/java/org/papertrail/database/DatabaseConnector.java
+++ b/src/main/java/org/papertrail/database/DatabaseConnector.java
@@ -1,7 +1,5 @@
package org.papertrail.database;
-import java.sql.SQLException;
-
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
@@ -16,7 +14,7 @@ public class DatabaseConnector {
private static HikariDataSource dataSource;
private final DSLContext dsl;
- public DatabaseConnector() throws SQLException {
+ public DatabaseConnector() {
initializeDataSource();
this.dsl = DSL.using(dataSource, SQLDialect.POSTGRES);
}
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
index 6b1e6694..9ea6ca2f 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java
@@ -3,6 +3,7 @@
import java.awt.Color;
import java.time.Instant;
import java.util.List;
+import java.util.Objects;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -42,12 +43,12 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
}
EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("π£ " +ProjectInfo.APPNAME+" Announcement: "+event.getOption("type").getAsString());
- eb.setDescription("π " +event.getOption("description").getAsString());
+ eb.setTitle("π£ " +ProjectInfo.APPNAME+" Announcement: "+ Objects.requireNonNull(event.getOption("type")).getAsString());
+ eb.setDescription("π " + Objects.requireNonNull(event.getOption("description")).getAsString());
eb.setThumbnail(AuthorInfo.AUTHOR_AVATAR_URL);
eb.setColor(Color.WHITE);
- eb.addField("π·οΈ Detail", "β°ββ€"+event.getOption("detail").getAsString(), false);
+ eb.addField("π·οΈ Detail", "β°ββ€"+ Objects.requireNonNull(event.getOption("detail")).getAsString(), false);
OptionMapping extra = event.getOption("extra");
if(extra!=null) {
eb.addField("π·οΈ Extras", "β°ββ€"+extra.getAsString(), false);
@@ -62,7 +63,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
for(String registeredChannel: registeredChannelList) {
TextChannel channelToSendTo = event.getJDA().getTextChannelById(registeredChannel);
if(channelToSendTo!=null) {
- event.getJDA().getTextChannelById(registeredChannel).sendMessageEmbeds(mb).queue(); // TODO implement rate-limitation beyond JDA's system
+ Objects.requireNonNull(event.getJDA().getTextChannelById(registeredChannel)).sendMessageEmbeds(mb).queue(); // TODO implement rate-limitation beyond JDA's system
}
}
}
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
index 725c2e6d..0330a924 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
@@ -1,6 +1,7 @@
package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
+import java.util.Objects;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -55,7 +56,7 @@ private void setAuditLogging(SlashCommandInteractionEvent event) {
return;
}
- String guildId = event.getGuild().getId();
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
// retrieve the previously registered channel_id associated with the given
// guild_id
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
@@ -114,7 +115,7 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
return;
}
- String guildId = event.getGuild().getId();
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
// retrieve the channel_id registered in the database
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
@@ -164,7 +165,7 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
return;
}
- String guildId = event.getGuild().getId();
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE);
if (registeredChannelId == null || registeredChannelId.isBlank()) {
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
index f46e3047..77b420e3 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
@@ -1,6 +1,7 @@
package org.papertrail.listeners.commandlisteners;
import java.awt.Color;
+import java.util.Objects;
import org.papertrail.database.DatabaseConnector;
import org.papertrail.database.TableNames;
@@ -58,7 +59,7 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
}
Guild guild = event.getGuild();
- String guildId = guild.getId();
+ String guildId = Objects.requireNonNull(guild).getId();
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
@@ -113,7 +114,7 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
}
Guild guild = event.getGuild();
- String guildId = guild.getId();
+ String guildId = Objects.requireNonNull(guild).getId();
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
// if there is no channel_id for the given guild_id in the database, then inform
@@ -154,7 +155,7 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
}
Guild guild = event.getGuild();
- String guildId = guild.getId();
+ String guildId = Objects.requireNonNull(guild).getId();
String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE);
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
index a7a81a0c..a0c641f4 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
@@ -25,15 +25,17 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
SelfUser botAsUser = event.getJDA().getSelfUser();
- Role botIntegrationRole = guild.getRoleByBot(botAsUser);
+ assert guild != null;
+ Role botIntegrationRole = guild.getRoleByBot(botAsUser);
Member botMember = guild.getMember(botAsUser);
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("PaperTrail Permissions Checker");
eb.setDescription("Helps determine whether the required permissions are granted for PaperTrail to function properly");
eb.setColor(Color.MAGENTA);
-
- eb.addField("Bot Integration Role Specific Permission", (botIntegrationRole.hasPermission(Permission.VIEW_AUDIT_LOGS) ? "β
" : "β")+Permission.VIEW_AUDIT_LOGS.getName(), false);
+
+ assert botIntegrationRole != null;
+ eb.addField("Bot Integration Role Specific Permission", (botIntegrationRole.hasPermission(Permission.VIEW_AUDIT_LOGS) ? "β
" : "β")+Permission.VIEW_AUDIT_LOGS.getName(), false);
// create a map of required permissions and set all their statuses to false
Map requiredPermissions = new EnumMap<>(Permission.class);
@@ -57,10 +59,10 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
});
StringBuilder finalPermissions = new StringBuilder();
- requiredPermissions.entrySet().forEach(permission -> {
- finalPermissions.append(Boolean.TRUE.equals(permission.getValue()) ? "β
" : "β");
- finalPermissions.append(permission.getKey().getName()+System.lineSeparator());
- });
+ requiredPermissions.forEach((key, value) -> {
+ finalPermissions.append(Boolean.TRUE.equals(value) ? "β
" : "β");
+ finalPermissions.append(key.getName()).append(System.lineSeparator());
+ });
eb.addField("Channel Specific Permissions: "+currentChannel.getAsMention(), finalPermissions.toString(), false);
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
index 5fb7c6fb..cde7ea0c 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java
@@ -3,6 +3,7 @@
import java.awt.Color;
import java.time.Instant;
import java.util.List;
+import java.util.Objects;
import org.papertrail.utilities.DurationFormatter;
@@ -22,11 +23,12 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
if(event.getName().equals("stats")) {
Guild guild = event.getGuild();
-
- List members = guild.getMemberCache().asList();
- Integer botCount = 0;
- Integer userCount = 0;
- Integer onlineUserCount = 0;
+
+ assert guild != null;
+ List members = Objects.requireNonNull(guild).getMemberCache().asList();
+ int botCount = 0;
+ int userCount = 0;
+ int onlineUserCount = 0;
for(Member member: members) {
if(member.getUser().isBot()) {
botCount++;
@@ -48,7 +50,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
eb.setColor(Color.PINK);
eb.addField("π Guild Name", "β°ββ€"+guild.getName(), false);
- eb.addField("π Guild Owner", "β°ββ€"+guild.getMemberById(guild.getOwnerId()).getAsMention(), false);
+ eb.addField("π Guild Owner", "β°ββ€"+ Objects.requireNonNull(guild.getMemberById(guild.getOwnerId())).getAsMention(), false);
eb.addField("π
Guild Created On", "β°ββ€"+DurationFormatter.isoToLocalTimeCounter(guild.getTimeCreated()), false);
eb.addField("π Guild Vanity URL", "β°ββ€"+(guild.getVanityUrl() !=null ? guild.getVanityUrl() : "Not Set"), false);
@@ -64,7 +66,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
eb.addField("π Guild Boosters ", "β°ββ€"+mentionableBoosters, false);
eb.addField("π Guild Boost Count", "β°ββ€"+guild.getBoostCount(), false);
eb.addField("π Booster Role", "β°ββ€"+(guild.getBoostRole() !=null ? guild.getBoostRole().getAsMention() : "No Boost Role Found"), false);
- eb.addField("πΌ Boost Tier", "β°ββ€"+guild.getBoostTier().toString(), false);
+ eb.addField("πΌ Boost Tier", "β°ββ€"+ guild.getBoostTier(), false);
eb.addField("π Locale", "β°ββ€"+guild.getLocale().getNativeName(), true);
eb.addField("π Verification", "β°ββ€"+guild.getVerificationLevel().name(), true);
@@ -73,7 +75,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
eb.addField("π¬ Text Channels", "β°ββ€"+guild.getTextChannels().size(), true);
eb.addField("π Voice Channels", "β°ββ€"+guild.getVoiceChannels().size(), true);
- eb.addField("π Data Requested By", "β°ββ€"+event.getMember().getAsMention(), false);
+ eb.addField("π Data Requested By", "β°ββ€"+ Objects.requireNonNull(event.getMember()).getAsMention(), false);
eb.setFooter("π Stats By: PaperTrail π");
eb.setTimestamp(Instant.now());
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
index edf4a829..a97813fe 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
@@ -1,10 +1,9 @@
package org.papertrail.listeners.loglisteners;
import java.awt.Color;
-import java.util.Arrays;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.concurrent.Executor;
import org.apache.commons.lang3.StringUtils;
@@ -171,7 +170,7 @@ private void formatGeneric(GuildAuditLogEntryCreateEvent event, AuditLogEntry al
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatInviteCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale , String channelIdToSendTo) {
@@ -232,7 +231,7 @@ private void formatInviteCreate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
@@ -289,7 +288,7 @@ private void formatInviteDelete(GuildAuditLogEntryCreateEvent event, AuditLogEnt
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatKick(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -317,10 +316,10 @@ private void formatKick(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale,
eb.addField("π With Reason", "β°ββ€"+(reason!=null ? reason : "No Reason Provided"), false);
eb.setFooter("Audit Log Entry ID: "+ale.getId());
- eb.setTimestamp(ale.getTimeCreated());
+ eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
- });
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ });
});
}
@@ -350,7 +349,7 @@ private void formatBan(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, S
eb.setFooter("Audit Log Entry ID: "+ale.getId());
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
});
});
}
@@ -379,7 +378,7 @@ private void formatUnban(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale,
eb.setFooter("Audit Log Entry ID: "+ale.getId());
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
});
});
}
@@ -396,7 +395,7 @@ private void formatMemberUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
String mentionableTarget = (target !=null ? target.getAsMention() : ale.getTargetId());
eb.setDescription("π€ **By**: "+mentionableExecutor+"\nβΉοΈ The following member was updated");
- eb.setThumbnail(event.getGuild().getMemberById(ale.getTargetId()).getEffectiveAvatarUrl());
+ eb.setThumbnail(Objects.requireNonNull(event.getGuild().getMemberById(ale.getTargetId())).getEffectiveAvatarUrl());
eb.setColor(Color.CYAN);
eb.addField("Action Type", String.valueOf(ale.getType()), true);
eb.addField("Target Type", String.valueOf(ale.getTargetType()), true);
@@ -425,9 +424,9 @@ private void formatMemberUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
case "nick":
if(oldValue!=null && newValue==null) { // resetting to default nickname
eb.addField("π·οΈ Nickname Update", "β°ββ€"+"Reset "+mentionableTarget+"'s name", false);
- } else if(oldValue!=null && newValue!=null) { // changing from one nickname to another
+ } else if(oldValue != null) { // changing from one nickname to another
eb.addField("π·οΈ Nickname Update", "β°ββ€"+"Updated "+mentionableTarget+"'s name from "+oldValue+ " to "+ newValue, false);
- } else if(oldValue==null && newValue!=null) { // changing from default nickname to a new nickname
+ } else if(newValue != null) { // changing from default nickname to a new nickname
eb.addField("π·οΈ Nickname Update", "β°ββ€"+"Set "+mentionableTarget+"'s name as "+ newValue, false);
}
break;
@@ -454,7 +453,7 @@ private void formatMemberUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatBotAdd(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -480,7 +479,7 @@ private void formatBotAdd(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatIntegrationCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -522,7 +521,7 @@ private void formatIntegrationCreate(GuildAuditLogEntryCreateEvent event, AuditL
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatIntegrationDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -564,7 +563,7 @@ private void formatIntegrationDelete(GuildAuditLogEntryCreateEvent event, AuditL
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -631,7 +630,7 @@ private void formatChannelCreate(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -725,7 +724,7 @@ private void formatChannelUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -775,7 +774,7 @@ private void formatChannelDelete(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelOverrideCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -848,7 +847,7 @@ private void formatChannelOverrideCreate(GuildAuditLogEntryCreateEvent event, Au
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelOverrideUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -875,13 +874,13 @@ private void formatChannelOverrideUpdate(GuildAuditLogEntryCreateEvent event, Au
String mentionableOverrideTarget = overriddenId;
if ("0".equals(overriddenType)) {
// Itβs a role
- Role role = event.getGuild().getRoleById(overriddenId);
+ Role role = event.getGuild().getRoleById(Objects.requireNonNull(overriddenId));
if (role != null) {
mentionableOverrideTarget = role.getAsMention();
}
} else if ("1".equals(overriddenType)) {
// Itβs a member
- Member member = event.getGuild().getMemberById(overriddenId);
+ Member member = event.getGuild().getMemberById(Objects.requireNonNull(overriddenId));
if (member != null) {
mentionableOverrideTarget = member.getAsMention();
}
@@ -923,7 +922,7 @@ private void formatChannelOverrideUpdate(GuildAuditLogEntryCreateEvent event, Au
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatChannelOverrideDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -963,7 +962,7 @@ private void formatChannelOverrideDelete(GuildAuditLogEntryCreateEvent event, Au
break;
case "allow":
- /// the newValue will return null if an over-ride is deleted but we're not concerned with newValue
+ // the newValue will return null if an over-ride is deleted but we're not concerned with newValue
// the oldValue returns the permissions the channel was previously allowed
eb.addField("Previously Allowed Permissions", PermissionResolver.getParsedPermissions(oldValue, "β
"), false);
break;
@@ -995,7 +994,7 @@ private void formatChannelOverrideDelete(GuildAuditLogEntryCreateEvent event, Au
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModRuleCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1023,13 +1022,13 @@ private void formatAutoModRuleCreate(GuildAuditLogEntryCreateEvent event, AuditL
case "exempt_roles":
String roleIds = String.valueOf(newValue);
String cleanedRoleIds = StringUtils.strip(roleIds, "[]");
- List roleIdList = Arrays.asList(StringUtils.split(cleanedRoleIds, ","));
+ String[] roleIdList = StringUtils.split(cleanedRoleIds, ",");
StringBuilder mentionableRoles = new StringBuilder();
for(String roleId : roleIdList) {
Role r = ale.getGuild().getRoleById(roleId.strip());
mentionableRoles.append(r!=null ? r.getAsMention() : roleId.strip()).append(", ");
}
- eb.addField("βοΈ Exempt Roles: ", "β°ββ€"+mentionableRoles.toString(), false);
+ eb.addField("βοΈ Exempt Roles: ", "β°ββ€"+ mentionableRoles, false);
break;
case "enabled":
@@ -1047,13 +1046,13 @@ private void formatAutoModRuleCreate(GuildAuditLogEntryCreateEvent event, AuditL
case "exempt_channels":
String channelIds = String.valueOf(newValue);
String cleanedChannelIds = StringUtils.strip(channelIds, "[]");
- List channelIdList = Arrays.asList(StringUtils.split(cleanedChannelIds, ","));
+ String[] channelIdList = StringUtils.split(cleanedChannelIds, ",");
StringBuilder mentionableChannels = new StringBuilder();
for(String channelId : channelIdList) {
GuildChannel r = ale.getGuild().getGuildChannelById(channelId.strip());
mentionableChannels.append(r!=null ? r.getAsMention() : channelId.strip()).append(", ");
}
- eb.addField("βοΈ Exempt Channels: ", "β°ββ€"+mentionableChannels.toString(), false);
+ eb.addField("βοΈ Exempt Channels: ", "β°ββ€"+ mentionableChannels, false);
break;
case "event_type":
@@ -1078,7 +1077,7 @@ private void formatAutoModRuleCreate(GuildAuditLogEntryCreateEvent event, AuditL
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModRuleDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1120,7 +1119,7 @@ private void formatAutoModRuleDelete(GuildAuditLogEntryCreateEvent event, AuditL
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModRuleUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1148,13 +1147,13 @@ private void formatAutoModRuleUpdate(GuildAuditLogEntryCreateEvent event, AuditL
case "exempt_roles":
String roleIds = String.valueOf(newValue);
String cleanedRoleIds = StringUtils.strip(roleIds, "[]");
- List roleIdList = Arrays.asList(StringUtils.split(cleanedRoleIds, ","));
+ String[] roleIdList = StringUtils.split(cleanedRoleIds, ",");
StringBuilder mentionableRoles = new StringBuilder();
for(String roleId : roleIdList) {
Role r = ale.getGuild().getRoleById(roleId.strip());
mentionableRoles.append(r!=null ? r.getAsMention() : roleId.strip()).append(", ");
}
- eb.addField("βοΈ New Exempt Roles: ", "β°ββ€"+mentionableRoles.toString(), false);
+ eb.addField("βοΈ New Exempt Roles: ", "β°ββ€"+ mentionableRoles, false);
break;
@@ -1165,13 +1164,13 @@ private void formatAutoModRuleUpdate(GuildAuditLogEntryCreateEvent event, AuditL
case "exempt_channels":
String channelIds = String.valueOf(newValue);
String cleanedChannelIds = StringUtils.strip(channelIds, "[]");
- List channelIdList = Arrays.asList(StringUtils.split(cleanedChannelIds, ","));
+ String[] channelIdList = StringUtils.split(cleanedChannelIds, ",");
StringBuilder mentionableChannels = new StringBuilder();
for(String channelId : channelIdList) {
GuildChannel r = ale.getGuild().getGuildChannelById(channelId.strip());
mentionableChannels.append(r!=null ? r.getAsMention() : channelId.strip()).append(", ");
}
- eb.addField("βοΈ New Exempt Channels: ", "β°ββ€"+mentionableChannels.toString(), false);
+ eb.addField("βοΈ New Exempt Channels: ", "β°ββ€"+ mentionableChannels, false);
break;
@@ -1193,7 +1192,7 @@ private void formatAutoModRuleUpdate(GuildAuditLogEntryCreateEvent event, AuditL
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatEmojiCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1233,7 +1232,7 @@ private void formatEmojiCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntr
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatEmojiUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1272,7 +1271,7 @@ private void formatEmojiUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntr
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatEmojiDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1311,7 +1310,7 @@ private void formatEmojiDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntr
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStickerCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1366,7 +1365,7 @@ private void formatStickerCreate(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStickerDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1419,7 +1418,7 @@ private void formatStickerDelete(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStickerUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1437,7 +1436,7 @@ private void formatStickerUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEn
eb.addField("Action Type", String.valueOf(ale.getType()), true);
eb.addField("Target Type", String.valueOf(ale.getTargetType()), true);
- eb.addField("π·οΈ Target Sticker Name", targetSticker.getName(), false);
+ eb.addField("π·οΈ Target Sticker Name", Objects.requireNonNull(targetSticker).getName(), false);
eb.addField("π Target Sticker Url", targetSticker.getIconUrl(), false);
for(Entry changes: ale.getChanges().entrySet()) {
@@ -1473,7 +1472,7 @@ private void formatStickerUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEn
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatGuildUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1580,7 +1579,7 @@ private void formatGuildUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntr
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatMemberRoleUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1594,7 +1593,7 @@ private void formatMemberRoleUpdate(GuildAuditLogEntryCreateEvent event, AuditLo
String mentionableTarget = (target !=null ? target.getAsMention() : ale.getTargetId());
eb.setDescription("π€ **By**: "+mentionableExecutor+"\nβΉοΈ The following member role was updated");
- eb.setThumbnail(event.getGuild().getMemberById(ale.getTargetIdLong()).getEffectiveAvatarUrl());
+ eb.setThumbnail(Objects.requireNonNull(event.getGuild().getMemberById(ale.getTargetIdLong())).getEffectiveAvatarUrl());
eb.setColor(Color.CYAN);
eb.addField("Action Type", String.valueOf(ale.getType()), true);
@@ -1634,7 +1633,7 @@ private void formatMemberRoleUpdate(GuildAuditLogEntryCreateEvent event, AuditLo
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatRoleCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1684,7 +1683,7 @@ private void formatRoleCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatRoleUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1758,7 +1757,7 @@ private void formatRoleUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatRoleDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1819,7 +1818,7 @@ private void formatRoleDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
// the audit log does not expose much information regarding member vc move and kick events
@@ -1841,7 +1840,7 @@ private void formatMemberVoiceKick(GuildAuditLogEntryCreateEvent event, AuditLog
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatMemberVoiceMove(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1861,7 +1860,7 @@ private void formatMemberVoiceMove(GuildAuditLogEntryCreateEvent event, AuditLog
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatVoiceChannelStatusUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1884,7 +1883,7 @@ private void formatVoiceChannelStatusUpdate(GuildAuditLogEntryCreateEvent event,
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatVoiceChannelStatusDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1907,7 +1906,7 @@ private void formatVoiceChannelStatusDelete(GuildAuditLogEntryCreateEvent event,
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModFlagToChannel(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1927,7 +1926,7 @@ private void formatAutoModFlagToChannel(GuildAuditLogEntryCreateEvent event, Aud
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModMemberTimeout (GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1947,7 +1946,7 @@ private void formatAutoModMemberTimeout (GuildAuditLogEntryCreateEvent event, Au
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatAutoModRuleBlockMessage (GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1967,7 +1966,7 @@ private void formatAutoModRuleBlockMessage (GuildAuditLogEntryCreateEvent event,
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatMessagePin(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -1987,7 +1986,7 @@ private void formatMessagePin(GuildAuditLogEntryCreateEvent event, AuditLogEntry
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
// these audit log events don't expose anything other than the executor of the event
private void formatMessageUnpin(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2007,7 +2006,7 @@ private void formatMessageUnpin(GuildAuditLogEntryCreateEvent event, AuditLogEnt
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStageInstanceCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2048,7 +2047,7 @@ private void formatStageInstanceCreate(GuildAuditLogEntryCreateEvent event, Audi
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStageInstanceUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2091,7 +2090,7 @@ private void formatStageInstanceUpdate(GuildAuditLogEntryCreateEvent event, Audi
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatStageInstanceDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2132,7 +2131,7 @@ private void formatStageInstanceDelete(GuildAuditLogEntryCreateEvent event, Audi
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatScheduledEventCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2192,7 +2191,7 @@ private void formatScheduledEventCreate(GuildAuditLogEntryCreateEvent event, Aud
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatScheduledEventUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2204,7 +2203,7 @@ private void formatScheduledEventUpdate(GuildAuditLogEntryCreateEvent event, Aud
String mentionableExecutor = (executor != null ? executor.getAsMention() : ale.getUserId());
ScheduledEvent targetEvent = event.getGuild().getScheduledEventById(ale.getTargetId());
- eb.setDescription("π€ **By**: "+mentionableExecutor+"\nβΉοΈ The following scheduled event was updated: "+targetEvent.getName());
+ eb.setDescription("π€ **By**: "+mentionableExecutor+"\nβΉοΈ The following scheduled event was updated: "+ Objects.requireNonNull(targetEvent).getName());
eb.setColor(Color.YELLOW);
eb.addField("Action Type", String.valueOf(ale.getType()), true);
eb.addField("Target Type", String.valueOf(ale.getTargetType()), true);
@@ -2260,7 +2259,7 @@ private void formatScheduledEventUpdate(GuildAuditLogEntryCreateEvent event, Aud
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatScheduledEventDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2320,7 +2319,7 @@ private void formatScheduledEventDelete(GuildAuditLogEntryCreateEvent event, Aud
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatThreadCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2383,7 +2382,7 @@ private void formatThreadCreate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatThreadUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2461,7 +2460,7 @@ private void formatThreadUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEnt
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatThreadDelete(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2520,7 +2519,7 @@ private void formatThreadDelete(GuildAuditLogEntryCreateEvent event, AuditLogEnt
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatWebhookCreate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2571,7 +2570,7 @@ private void formatWebhookCreate(GuildAuditLogEntryCreateEvent event, AuditLogEn
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatWebhookUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2622,7 +2621,7 @@ private void formatWebhookUpdate(GuildAuditLogEntryCreateEvent event, AuditLogEn
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
private void formatWebhookRemove(GuildAuditLogEntryCreateEvent event, AuditLogEntry ale, String channelIdToSendTo) {
@@ -2673,6 +2672,6 @@ private void formatWebhookRemove(GuildAuditLogEntryCreateEvent event, AuditLogEn
eb.setTimestamp(ale.getTimeCreated());
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
}
}
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
index 2e2114f4..500abb2b 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
@@ -93,7 +93,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
// fetch the old message content and its author from the database
AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
- if(ame==null || ame.getAuthorId()==null || ame.getAuthorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
+ if(ame==null || ame.authorId()==null || ame.authorId().isBlank()) { // would be true only if the unedited message was not logged in the first place
return;
}
// fetch the updated message and its author from the event
@@ -101,7 +101,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
// Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
// This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
- if(updatedMessage.equals(ame.getMessageContent())) {
+ if(updatedMessage.equals(ame.messageContent())) {
return;
}
@@ -110,7 +110,7 @@ public void onMessageUpdate(MessageUpdateEvent event) {
eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
eb.setColor(Color.YELLOW);
- eb.addField("Old Message", ame.getMessageContent(), false); // get only the message and not the author
+ eb.addField("Old Message", ame.messageContent(), false); // get only the message and not the author
eb.addField("New Message", updatedMessage, false);
eb.setFooter(event.getGuild().getName());
@@ -152,14 +152,14 @@ public void onMessageDelete(MessageDeleteEvent event) {
// retrieve the stored message in the database which was deleted
AuthorAndMessageEntity ame = dc.getMessageDataAccess().retrieveAuthorAndMessage(messageId);
- User author = event.getJDA().getUserById(ame.getAuthorId());
- String mentionableAuthor = (author !=null ? author.getAsMention() : ame.getAuthorId());
+ User author = event.getJDA().getUserById(ame.authorId());
+ String mentionableAuthor = (author !=null ? author.getAsMention() : ame.authorId());
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("ποΈ Message Delete Event");
eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
eb.setColor(Color.RED);
- eb.addField("Deleted Message", ame.getMessageContent(), false);
+ eb.addField("Deleted Message", ame.messageContent(), false);
eb.setFooter(event.getGuild().getName());
eb.setTimestamp(Instant.now());
diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
index 27be2c82..47bd0f6d 100644
--- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
+++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
@@ -2,6 +2,7 @@
import java.awt.Color;
import java.time.Instant;
+import java.util.Objects;
import java.util.concurrent.Executor;
import org.jetbrains.annotations.NotNull;
@@ -59,7 +60,7 @@ public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
});
}
@@ -92,7 +93,7 @@ public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
});
}
diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
index ef3d2582..61a7c7a0 100644
--- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
+++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
@@ -2,6 +2,7 @@
import java.awt.Color;
import java.time.Instant;
+import java.util.Objects;
import java.util.concurrent.Executor;
import org.jetbrains.annotations.NotNull;
@@ -71,7 +72,7 @@ public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) {
MessageEmbed mb = eb.build();
- event.getGuild().getTextChannelById(registeredChannelId).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
});
}
}
diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java
index 5def22d4..28f155df 100644
--- a/src/main/java/org/papertrail/main/FireRun.java
+++ b/src/main/java/org/papertrail/main/FireRun.java
@@ -3,7 +3,6 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.Security;
-import java.sql.SQLException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -46,7 +45,7 @@ private static void registerBouncyCastle() {
}
}
- public static void main(String[] args) throws IOException, SQLException {
+ public static void main(String[] args) throws IOException {
registerBouncyCastle();
diff --git a/src/main/java/org/papertrail/utilities/TypeResolver.java b/src/main/java/org/papertrail/utilities/TypeResolver.java
index 0c0f56a1..5a086e02 100644
--- a/src/main/java/org/papertrail/utilities/TypeResolver.java
+++ b/src/main/java/org/papertrail/utilities/TypeResolver.java
@@ -157,7 +157,7 @@ public static String guildVerificationLevelResolver(Object type) {
}
try {
- Integer t = Integer.parseInt(type.toString());
+ int t = Integer.parseInt(type.toString());
return switch (t) {
case 0 -> "NONE";
case 1 -> "LOW (Verified Email)";
@@ -178,7 +178,7 @@ public static String explicitFilterTypeResolver(Object type) {
}
try {
- Integer t = Integer.parseInt(type.toString());
+ int t = Integer.parseInt(type.toString());
return switch (t) {
case 0 -> "No Filter";
case 1 -> "Filter Messages From Server Members Without Roles";
@@ -197,7 +197,7 @@ public static String scheduleEventTypeResolver(Object type) {
}
try {
- Integer t = Integer.parseInt(type.toString());
+ int t = Integer.parseInt(type.toString());
return switch (t) {
case 1 -> "Stage Event";
case 2 -> "Voice Event";
@@ -216,7 +216,7 @@ public static String scheduleEventStatusTypeResolver(Object type) {
}
try {
- Integer t = Integer.parseInt(type.toString());
+ int t = Integer.parseInt(type.toString());
return switch (t) {
case 1 -> "Scheduled";
case 2 -> "Active";
From 2d085b5263ada287267cb5d3e48175c674081f3b Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Sun, 20 Jul 2025 10:13:08 +0530
Subject: [PATCH 15/16] Show multiple required permissions for bot role
Updated the embed field to display both VIEW_AUDIT_LOGS and MANAGE_SERVER permissions for the bot integration role, providing clearer visibility of required permissions.
---
.../RequiredPermissionCheckCommandListener.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
index a0c641f4..95b88a56 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java
@@ -35,7 +35,13 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
eb.setColor(Color.MAGENTA);
assert botIntegrationRole != null;
- eb.addField("Bot Integration Role Specific Permission", (botIntegrationRole.hasPermission(Permission.VIEW_AUDIT_LOGS) ? "β
" : "β")+Permission.VIEW_AUDIT_LOGS.getName(), false);
+ String botRoleRequiredPermissions = (botIntegrationRole.hasPermission(Permission.VIEW_AUDIT_LOGS) ? "β
" : "β") +
+ Permission.VIEW_AUDIT_LOGS.getName() +
+ System.lineSeparator() +
+ (botIntegrationRole.hasPermission(Permission.MANAGE_SERVER) ? "β
" : "β") +
+ Permission.MANAGE_SERVER.getName();
+
+ eb.addField("Bot Integration Role Specific Permission", botRoleRequiredPermissions, false);
// create a map of required permissions and set all their statuses to false
Map requiredPermissions = new EnumMap<>(Permission.class);
From 79074a0c2e14e67d4aee727284b270a14d8c1eb4 Mon Sep 17 00:00:00 2001
From: Egg-03 <111327101+Egg-03@users.noreply.github.com>
Date: Sun, 20 Jul 2025 10:41:23 +0530
Subject: [PATCH 16/16] Remove obsolete TODO comments for logging
Deleted TODO comments about adding logging in GuildDataAccess and MessageDataAccess classes. No functional changes were made.
---
src/main/java/org/papertrail/database/GuildDataAccess.java | 1 -
src/main/java/org/papertrail/database/MessageDataAccess.java | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/java/org/papertrail/database/GuildDataAccess.java b/src/main/java/org/papertrail/database/GuildDataAccess.java
index f5ac1b8a..bd5dbdfe 100644
--- a/src/main/java/org/papertrail/database/GuildDataAccess.java
+++ b/src/main/java/org/papertrail/database/GuildDataAccess.java
@@ -8,7 +8,6 @@
import static org.jooq.impl.DSL.selectOne;
import static org.jooq.impl.DSL.table;
-// TODO Add logging
public class GuildDataAccess {
private final DSLContext dsl;
diff --git a/src/main/java/org/papertrail/database/MessageDataAccess.java b/src/main/java/org/papertrail/database/MessageDataAccess.java
index 4f4001dc..f39596ad 100644
--- a/src/main/java/org/papertrail/database/MessageDataAccess.java
+++ b/src/main/java/org/papertrail/database/MessageDataAccess.java
@@ -6,7 +6,7 @@
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.selectOne;
import static org.jooq.impl.DSL.table;
-// TODO Add Logging
+
public class MessageDataAccess {
private final DSLContext dsl;