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..b6667fe1 100644 --- a/pom.xml +++ b/pom.xml @@ -38,11 +38,21 @@ dotenv-java 3.2.0 + + com.zaxxer + HikariCP + 6.3.0 + org.postgresql postgresql 42.7.7 + + org.jooq + jooq + 3.20.5 + org.apache.commons commons-lang3 @@ -57,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/cleanup/BotKickListener.java b/src/main/java/org/papertrail/cleanup/BotKickListener.java index ee437900..ceba7f9e 100644 --- a/src/main/java/org/papertrail/cleanup/BotKickListener.java +++ b/src/main/java/org/papertrail/cleanup/BotKickListener.java @@ -1,34 +1,36 @@ package org.papertrail.cleanup; -import java.sql.SQLException; - 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; - - public BotKickListener(DatabaseConnector dc) { - this.dc=dc; + + private final Executor vThreadPool; + private final DatabaseConnector dc; + + public BotKickListener(DatabaseConnector dc, Executor vThreadPool) { + this.dc = dc; + this.vThreadPool = vThreadPool; } - + @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()); - } + vThreadPool.execute(()->{ + dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.AUDIT_LOG_TABLE); + dc.getGuildDataAccess().unregister(leftGuild.getId(), TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + }); + } } 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..98fe2dae --- /dev/null +++ b/src/main/java/org/papertrail/database/AuthorAndMessageEntity.java @@ -0,0 +1,6 @@ +package org.papertrail.database; + +public record AuthorAndMessageEntity(String authorId, String messageContent) { + + +} diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java index 8dc95eae..f8bb6468 100644 --- a/src/main/java/org/papertrail/database/DatabaseConnector.java +++ b/src/main/java/org/papertrail/database/DatabaseConnector.java @@ -1,231 +1,51 @@ package org.papertrail.database; -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; +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; - private Connection connect; - - public DatabaseConnector() throws SQLException { - connect = DriverManager.getConnection(DB_URL); + public DatabaseConnector() { + initializeDataSource(); + this.dsl = DSL.using(dataSource, SQLDialect.POSTGRES); } - - 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 GuildDataAccess getGuildDataAccess() { + return new GuildDataAccess(dsl); } - 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(); - } + public MessageDataAccess getMessageDataAccess() { + return new MessageDataAccess(dsl); } - public List retrieveAllRegisteredChannels(String tableName) { - - String sqlStatement = "SELECT channel_id FROM " + tableName; - List channels = new ArrayList<>(); + private static synchronized void initializeDataSource() { - 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(); + 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."); + } + })); } - - 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 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 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/GuildDataAccess.java b/src/main/java/org/papertrail/database/GuildDataAccess.java new file mode 100644 index 00000000..bd5dbdfe --- /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..f39596ad --- /dev/null +++ b/src/main/java/org/papertrail/database/MessageDataAccess.java @@ -0,0 +1,61 @@ +package org.papertrail.database; + +import org.jooq.DSLContext; +import org.papertrail.utilities.MessageEncryption; + +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 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 -> 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) { + + 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(Long.parseLong(messageId))) + .execute(); + } +} diff --git a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java similarity index 68% rename from src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java rename to src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java index 7ee5672f..9ea6ca2f 100644 --- a/src/main/java/org/papertrail/listeners/customlisteners/AnnouncementListener.java +++ b/src/main/java/org/papertrail/listeners/commandlisteners/AnnouncementCommandListener.java @@ -1,8 +1,9 @@ -package org.papertrail.listeners.customlisteners; +package org.papertrail.listeners.commandlisteners; 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; @@ -17,11 +18,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; } @@ -35,18 +36,19 @@ 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; } 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); @@ -61,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/loglisteners/AuditLogCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java similarity index 86% rename from src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java rename to src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java index bcb07ea2..0330a924 100644 --- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java +++ b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java @@ -1,7 +1,7 @@ -package org.papertrail.listeners.loglisteners; +package org.papertrail.listeners.commandlisteners; import java.awt.Color; -import java.sql.SQLException; +import java.util.Objects; import org.papertrail.database.DatabaseConnector; import org.papertrail.database.TableNames; @@ -15,12 +15,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; + private final DatabaseConnector dc; - public AuditLogCommandListener(DatabaseConnector dc) { + public AuditLogSetupCommandListener(DatabaseConnector dc) { this.dc = dc; } @@ -56,10 +56,10 @@ 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.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 +83,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 +93,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"); @@ -115,10 +115,10 @@ 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.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 @@ -165,8 +165,8 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) { return; } - String guildId = event.getGuild().getId(); - String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + String guildId = Objects.requireNonNull(event.getGuild()).getId(); + String registeredChannelId = dc.getGuildDataAccess().retrieveRegisteredChannel(guildId, TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { @@ -180,7 +180,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 +190,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/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 84% rename from src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java rename to src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java index 3cb11ebe..77b420e3 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java +++ b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java @@ -1,7 +1,7 @@ -package org.papertrail.listeners.messagelisteners; +package org.papertrail.listeners.commandlisteners; import java.awt.Color; -import java.sql.SQLException; +import java.util.Objects; import org.papertrail.database.DatabaseConnector; import org.papertrail.database.TableNames; @@ -16,12 +16,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 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); @@ -59,9 +59,9 @@ private void setMessageLogging(SlashCommandInteractionEvent event) { } Guild guild = event.getGuild(); - String guildId = guild.getId(); + String guildId = Objects.requireNonNull(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 +79,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 +89,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); @@ -114,9 +114,9 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) { } Guild guild = event.getGuild(); - String guildId = guild.getId(); + String guildId = Objects.requireNonNull(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()) { @@ -155,9 +155,9 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) { } Guild guild = event.getGuild(); - String guildId = guild.getId(); + String guildId = Objects.requireNonNull(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 +171,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 +180,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/customlisteners/RequiredPermissionCheckListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java similarity index 69% rename from src/main/java/org/papertrail/listeners/customlisteners/RequiredPermissionCheckListener.java rename to src/main/java/org/papertrail/listeners/commandlisteners/RequiredPermissionCheckCommandListener.java index 7b7c799e..95b88a56 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) { @@ -25,15 +25,23 @@ 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; + 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); @@ -57,10 +65,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/customlisteners/ServerStatListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java similarity index 81% rename from src/main/java/org/papertrail/listeners/customlisteners/ServerStatListener.java rename to src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java index b8a1f5c3..cde7ea0c 100644 --- a/src/main/java/org/papertrail/listeners/customlisteners/ServerStatListener.java +++ b/src/main/java/org/papertrail/listeners/commandlisteners/ServerStatCommandListener.java @@ -1,8 +1,9 @@ -package org.papertrail.listeners.customlisteners; +package org.papertrail.listeners.commandlisteners; import java.awt.Color; import java.time.Instant; import java.util.List; +import java.util.Objects; import org.papertrail.utilities.DurationFormatter; @@ -14,7 +15,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) { @@ -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/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/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java index 5e81ad1a..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.retrieveRegisteredChannelId(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 6c02a65b..a97813fe 100644 --- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java +++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java @@ -1,12 +1,13 @@ 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; +import org.jetbrains.annotations.NotNull; import org.papertrail.database.DatabaseConnector; import org.papertrail.database.TableNames; import org.papertrail.utilities.ColorFormatter; @@ -35,24 +36,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.retrieveRegisteredChannelId(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) { @@ -165,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) { @@ -226,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(); } @@ -283,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) { @@ -311,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(); + }); }); } @@ -344,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(); }); }); } @@ -373,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(); }); }); } @@ -390,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); @@ -419,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; @@ -448,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) { @@ -474,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) { @@ -516,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) { @@ -558,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) { @@ -625,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) { @@ -719,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) { @@ -769,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) { @@ -842,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) { @@ -869,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(); } @@ -917,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) { @@ -957,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; @@ -989,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) { @@ -1017,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": @@ -1041,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": @@ -1072,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) { @@ -1114,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) { @@ -1142,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; @@ -1159,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; @@ -1187,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) { @@ -1227,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) { @@ -1266,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) { @@ -1305,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) { @@ -1360,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) { @@ -1413,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) { @@ -1431,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()) { @@ -1467,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) { @@ -1574,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) { @@ -1588,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); @@ -1628,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) { @@ -1678,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) { @@ -1752,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) { @@ -1813,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 @@ -1835,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) { @@ -1855,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) { @@ -1878,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) { @@ -1901,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) { @@ -1921,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) { @@ -1941,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) { @@ -1961,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) { @@ -1981,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) { @@ -2001,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) { @@ -2042,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) { @@ -2085,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) { @@ -2126,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) { @@ -2186,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) { @@ -2198,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); @@ -2254,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) { @@ -2314,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) { @@ -2377,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) { @@ -2455,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) { @@ -2514,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) { @@ -2565,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) { @@ -2616,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) { @@ -2667,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 new file mode 100644 index 00000000..500abb2b --- /dev/null +++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java @@ -0,0 +1,177 @@ +package org.papertrail.listeners.loglisteners; + +import java.awt.Color; +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; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageDeleteEvent; +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) { + + // if the author is a bot or system, don't log + if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { + return; + } + // don't register non-textual contents + 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 + vThreadPool.execute(()-> { + String messageId = event.getMessageId(); + withMessageLock(messageId, ()-> dc.getMessageDataAccess().logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId())); + }); + + + } + + @Override + public void onMessageUpdate(MessageUpdateEvent event) { + + if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { + return; + } + + String guildId = event.getGuild().getId(); + if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) { + return; + } + + 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.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 + 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.messageContent())) { + 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.messageContent(), 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 + 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. + + // 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); + Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue(); + }); + } + + @Override + public void onMessageDelete(MessageDeleteEvent event) { + + String guildId = event.getGuild().getId(); + + if(!dc.getGuildDataAccess().isGuildRegistered(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE)) { + return; + } + + 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.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.messageContent(), false); + + eb.setFooter(event.getGuild().getName()); + eb.setTimestamp(Instant.now()); + + // delete the message from the database + 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. + + // send the fetched deleted message to the logging channel + MessageEmbed mb = eb.build(); + Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue(); + }); + } +} 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/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java index b34770e9..47bd0f6d 100644 --- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java +++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java @@ -2,7 +2,10 @@ import java.awt.Color; import java.time.Instant; +import java.util.Objects; +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 +19,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.retrieveRegisteredChannelId(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(); + + Objects.requireNonNull(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.retrieveRegisteredChannelId(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(); + + Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue(); + }); } + } diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java deleted file mode 100644 index 93f6726e..00000000 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ /dev/null @@ -1,176 +0,0 @@ -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.DatabaseConnector; -import org.papertrail.database.TableNames; -import org.tinylog.Logger; - -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.message.MessageDeleteEvent; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import net.dv8tion.jda.api.events.message.MessageUpdateEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; - -public class MessageLogListener extends ListenerAdapter { - - private DatabaseConnector dc; - public MessageLogListener(DatabaseConnector dc) { - this.dc = 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; - } - // don't register non-textual contents - 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 - String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); - - // if not registered, exit - if(registeredGuildId==null) { - 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(); - } - } - } - - @Override - public void onMessageUpdate(MessageUpdateEvent event) { - - if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { - return; - } - - - String guildId = event.getGuild().getId(); - - String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); - if(registeredGuildId==null) { - 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(); - } - } - } - - @Override - public void onMessageDelete(MessageDeleteEvent event) { - - String guildId = event.getGuild().getId(); - - String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); - if(registeredGuildId==null) { - 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(); - - } - } - } -} 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/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java index 68faeb85..61a7c7a0 100644 --- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java +++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java @@ -2,7 +2,10 @@ import java.awt.Color; import java.time.Instant; +import java.util.Objects; +import java.util.concurrent.Executor; +import org.jetbrains.annotations.NotNull; import org.papertrail.database.DatabaseConnector; import org.papertrail.database.TableNames; @@ -14,58 +17,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.retrieveRegisteredChannelId(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(); + + Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue(); + }); } } 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/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java index e1e8d0a1..28f155df 100644 --- a/src/main/java/org/papertrail/main/FireRun.java +++ b/src/main/java/org/papertrail/main/FireRun.java @@ -3,22 +3,24 @@ 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; +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; @@ -29,7 +31,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() { @@ -40,27 +45,31 @@ private static void registerBouncyCastle() { } } - public static void main(String[] args) throws IOException, SQLException { + public static void main(String[] args) throws IOException { registerBouncyCastle(); 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, vThreadPool)); + + manager.addEventListener(new MessageLogSetupCommandListener(dc)); + manager.addEventListener(new MessageLogListener(dc, vThreadPool)); + + 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()); + 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 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"), 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";