diff --git a/pom.xml b/pom.xml index d090bf4..3c8cee5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 net.pcsx2 HifumiBot - 4.9.2 + 4.10.0 21 21 diff --git a/src/main/java/net/pcsx2/hifumi/database/Database.java b/src/main/java/net/pcsx2/hifumi/database/Database.java index 90afc77..9610ee8 100644 --- a/src/main/java/net/pcsx2/hifumi/database/Database.java +++ b/src/main/java/net/pcsx2/hifumi/database/Database.java @@ -10,6 +10,20 @@ import java.util.List; import java.util.Optional; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.Message.Attachment; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.events.automod.AutoModExecutionEvent; +import net.dv8tion.jda.api.events.guild.GuildBanEvent; +import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; +import net.dv8tion.jda.api.events.message.MessageBulkDeleteEvent; +import net.dv8tion.jda.api.events.message.MessageDeleteEvent; +import net.dv8tion.jda.api.events.message.MessageUpdateEvent; +import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent; +import net.dv8tion.jda.api.events.user.update.UserUpdateNameEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; import net.pcsx2.hifumi.HifumiBot; import net.pcsx2.hifumi.charting.AutomodChartData; import net.pcsx2.hifumi.charting.MemberChartData; @@ -27,27 +41,12 @@ import net.pcsx2.hifumi.util.TimeUtils; import net.pcsx2.hifumi.util.UserUtils; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.Message.Attachment; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.automod.AutoModResponse; -import net.dv8tion.jda.api.events.automod.AutoModExecutionEvent; -import net.dv8tion.jda.api.events.guild.GuildBanEvent; -import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; -import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; -import net.dv8tion.jda.api.events.message.MessageBulkDeleteEvent; -import net.dv8tion.jda.api.events.message.MessageDeleteEvent; -import net.dv8tion.jda.api.events.message.MessageUpdateEvent; -import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent; -import net.dv8tion.jda.api.events.user.update.UserUpdateNameEvent; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; - public class Database { /** * Store user, channel, message, attachment, and event records */ - public static void insertMessage(Message message, boolean skipEvent) { + public static void insertMessage(Message message) { Connection conn = HifumiBot.getSelf().getSQLite().getConnection(); try { @@ -75,7 +74,7 @@ INSERT INTO channel (discord_id, name) // Check if the referenced message exists in the database; if not, try to add it first. if (message.getReferencedMessage() != null) { if (Database.getLatestMessage(message.getReferencedMessage().getIdLong()) == null) { - Database.insertMessage(message.getReferencedMessage(), skipEvent); + Database.insertMessage(message.getReferencedMessage()); } } @@ -99,7 +98,7 @@ INSERT INTO message (message_id, fk_channel, jump_link, fk_reply_to_message, tim insertMessage.executeUpdate(); insertMessage.close(); - if (!skipEvent) { + if (!HifumiBot.getSelf().getPermissionManager().hasMessageLogBypass(message)) { PreparedStatement insertEvent = conn.prepareStatement(""" INSERT INTO message_event (fk_user, fk_message, timestamp, action, content) VALUES (?, ?, ?, ?, ?); @@ -308,39 +307,41 @@ INSERT INTO message (message_id, fk_channel, fk_user) insertMessage.executeUpdate(); insertMessage.close(); - List attachments = event.getMessage().getAttachments(); + if (!HifumiBot.getSelf().getPermissionManager().hasMessageLogBypass(event.getMessage())) { + List attachments = event.getMessage().getAttachments(); - if (!attachments.isEmpty()) { - PreparedStatement insertAttachment = conn.prepareStatement(""" - INSERT INTO message_attachment (discord_id, timestamp, fk_message, content_type, proxy_url) - VALUES (?, ?, ?, ?, ?) - ON CONFLICT (discord_id) DO NOTHING; - """); + if (!attachments.isEmpty()) { + PreparedStatement insertAttachment = conn.prepareStatement(""" + INSERT INTO message_attachment (discord_id, timestamp, fk_message, content_type, proxy_url) + VALUES (?, ?, ?, ?, ?) + ON CONFLICT (discord_id) DO NOTHING; + """); - for (Attachment attachment : attachments) { - insertAttachment.setLong(1, attachment.getIdLong()); - insertAttachment.setLong(2, attachment.getTimeCreated().toEpochSecond()); - insertAttachment.setLong(3, event.getMessageIdLong()); - insertAttachment.setString(4, attachment.getContentType()); - insertAttachment.setString(5, attachment.getProxyUrl()); - insertAttachment.addBatch(); + for (Attachment attachment : attachments) { + insertAttachment.setLong(1, attachment.getIdLong()); + insertAttachment.setLong(2, attachment.getTimeCreated().toEpochSecond()); + insertAttachment.setLong(3, event.getMessageIdLong()); + insertAttachment.setString(4, attachment.getContentType()); + insertAttachment.setString(5, attachment.getProxyUrl()); + insertAttachment.addBatch(); + } + + insertAttachment.executeBatch(); + insertAttachment.close(); } - - insertAttachment.executeBatch(); - insertAttachment.close(); - } - PreparedStatement insertEvent = conn.prepareStatement(""" - INSERT INTO message_event (fk_user, fk_message, timestamp, action, content) - VALUES (?, ?, ?, ?, ?); - """); - insertEvent.setLong(1, event.getAuthor().getIdLong()); - insertEvent.setLong(2, event.getMessageIdLong()); - insertEvent.setLong(3, (event.getMessage().getTimeEdited() != null ? event.getMessage().getTimeEdited() : event.getMessage().getTimeCreated()).toEpochSecond()); - insertEvent.setString(4, "edit"); - insertEvent.setString(5, event.getMessage().getContentRaw()); - insertEvent.executeUpdate(); - insertEvent.close(); + PreparedStatement insertEvent = conn.prepareStatement(""" + INSERT INTO message_event (fk_user, fk_message, timestamp, action, content) + VALUES (?, ?, ?, ?, ?); + """); + insertEvent.setLong(1, event.getAuthor().getIdLong()); + insertEvent.setLong(2, event.getMessageIdLong()); + insertEvent.setLong(3, (event.getMessage().getTimeEdited() != null ? event.getMessage().getTimeEdited() : event.getMessage().getTimeCreated()).toEpochSecond()); + insertEvent.setString(4, "edit"); + insertEvent.setString(5, event.getMessage().getContentRaw()); + insertEvent.executeUpdate(); + insertEvent.close(); + } } catch (SQLException e) { Messaging.logException("Database", "insertMessageUpdateEvent", e); } diff --git a/src/main/java/net/pcsx2/hifumi/event/MessageEventListener.java b/src/main/java/net/pcsx2/hifumi/event/MessageEventListener.java index d05d032..9e3c875 100644 --- a/src/main/java/net/pcsx2/hifumi/event/MessageEventListener.java +++ b/src/main/java/net/pcsx2/hifumi/event/MessageEventListener.java @@ -49,12 +49,9 @@ public void onMessageReceived(MessageReceivedEvent event) { // Make note of Hifumi's identity and elevation for later String hifumiUserId = HifumiBot.getSelf().getJDA().getSelfUser().getId(); - boolean hasElevatedPerms = HifumiBot.getSelf().getPermissionManager().hasPermission(PermissionLevel.ADMIN, event.getMember()); boolean isHifumi = event.getAuthor().getId().equals(hifumiUserId); - // Store all messages, exclude highly privileged users - boolean skipEvent = hasElevatedPerms || isHifumi; - Database.insertMessage(event.getMessage(), skipEvent); + Database.insertMessage(event.getMessage()); // If the sender was the bot, do not process any further. if (isHifumi) { diff --git a/src/main/java/net/pcsx2/hifumi/permissions/PermissionManager.java b/src/main/java/net/pcsx2/hifumi/permissions/PermissionManager.java index f1645be..a751d32 100644 --- a/src/main/java/net/pcsx2/hifumi/permissions/PermissionManager.java +++ b/src/main/java/net/pcsx2/hifumi/permissions/PermissionManager.java @@ -24,13 +24,17 @@ package net.pcsx2.hifumi.permissions; import java.util.ArrayList; +import java.util.Optional; -import net.pcsx2.hifumi.HifumiBot; - +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Role; +import net.pcsx2.hifumi.HifumiBot; +import net.pcsx2.hifumi.util.MemberUtils; public class PermissionManager { + private String superuserId; public PermissionManager(String superuserId) { @@ -51,6 +55,8 @@ public PermissionManager(String superuserId) { if (HifumiBot.getSelf().getConfig().permissions.superAdminRoleIds == null) { HifumiBot.getSelf().getConfig().permissions.superAdminRoleIds = new ArrayList(); } + + this.validateRoles(); } public boolean hasPermission(PermissionLevel permissionLevel, Member member) { @@ -93,4 +99,49 @@ public boolean hasPermission(PermissionLevel permissionLevel, Member member) { return false; } } + + public boolean hasPermission(PermissionRole permissionRole, Member member) { + if (permissionRole != null && member != null) { + for (Role role : member.getRoles()) { + if (role.getName().equals(permissionRole.toString())) { + return true; + } + } + } + + return false; + } + + /** + * Convenience method to simplify checking if a message's author has the log bypass permission. + * @param message - The message to check + * @return True if the author has the bypass permission, false otherwise. + */ + public boolean hasMessageLogBypass(Message message) { + if (message.getChannelType().isGuild()) { + Guild server = message.getGuild(); + Optional memberOpt = MemberUtils.getOrRetrieveMember(server, message.getAuthor().getId()); + + if (memberOpt.isPresent()) { + return this.hasPermission(PermissionRole.MESSAGE_LOG_BYPASS_ROLE, memberOpt.get()); + } + } + + return false; + } + + private void validateRoles(String... roleNames) { + for (Guild server : HifumiBot.getSelf().getJDA().getGuilds()) { + for (PermissionRole permissionRole : PermissionRole.values()) { + String roleName = permissionRole.toString(); + + if (server.getRolesByName(roleName, true).isEmpty()) { + server.createRole() + .setName(roleName) + .setMentionable(false) + .queue(); + } + } + } + } } diff --git a/src/main/java/net/pcsx2/hifumi/permissions/PermissionRole.java b/src/main/java/net/pcsx2/hifumi/permissions/PermissionRole.java new file mode 100644 index 0000000..da531a7 --- /dev/null +++ b/src/main/java/net/pcsx2/hifumi/permissions/PermissionRole.java @@ -0,0 +1,23 @@ +package net.pcsx2.hifumi.permissions; + +public enum PermissionRole +{ + MESSAGE_LOG_BYPASS_ROLE("Hifumi MLB"); + + private String roleName; + + private PermissionRole(String roleName) + { + this.roleName = roleName; + } + + /** + * Resolve this enum to the display name of the Role it is supposed to represent. + * @return String value of the role's display name + */ + @Override + public String toString() + { + return this.roleName; + } +}