From e32649df50746f6a328c73f50b9dc694894f3c09 Mon Sep 17 00:00:00 2001 From: ddivad195 Date: Sun, 25 Jul 2021 12:23:06 +0100 Subject: [PATCH 1/6] feat: update to latest discordkt snapshot --- src/main/kotlin/me/ddivad/judgebot/Main.kt | 11 +- .../judgebot/arguments/LowerMemberArg.kt | 10 +- .../ddivad/judgebot/arguments/LowerUserArg.kt | 7 +- .../ddivad/judgebot/commands/GuildCommands.kt | 9 +- .../ddivad/judgebot/commands/InfoCommands.kt | 10 +- .../judgebot/commands/InfractionCommands.kt | 25 ++-- .../ddivad/judgebot/commands/MuteCommands.kt | 8 +- .../ddivad/judgebot/commands/NoteCommands.kt | 11 +- .../ddivad/judgebot/commands/RuleCommands.kt | 15 +-- .../ddivad/judgebot/commands/UserCommands.kt | 27 ++-- .../judgebot/commands/UtilityCommands.kt | 2 + .../judgebot/dataclasses/Permissions.kt | 48 +++++++ .../listeners/MemberReactionListeners.kt | 45 ++++--- .../listeners/StaffReactionListeners.kt | 125 +++++++++--------- .../ddivad/judgebot/services/HelpService.kt | 10 +- .../judgebot/services/PermissionsService.kt | 61 --------- 16 files changed, 193 insertions(+), 231 deletions(-) create mode 100644 src/main/kotlin/me/ddivad/judgebot/dataclasses/Permissions.kt delete mode 100644 src/main/kotlin/me/ddivad/judgebot/services/PermissionsService.kt diff --git a/src/main/kotlin/me/ddivad/judgebot/Main.kt b/src/main/kotlin/me/ddivad/judgebot/Main.kt index 55cd588..a51afba 100644 --- a/src/main/kotlin/me/ddivad/judgebot/Main.kt +++ b/src/main/kotlin/me/ddivad/judgebot/Main.kt @@ -6,6 +6,7 @@ import dev.kord.gateway.Intent import dev.kord.gateway.Intents import dev.kord.gateway.PrivilegedIntent import me.ddivad.judgebot.dataclasses.Configuration +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.services.* import me.ddivad.judgebot.services.infractions.BanService import me.ddivad.judgebot.services.infractions.MuteService @@ -31,6 +32,7 @@ suspend fun main(args: Array) { commandReaction = null theme = Color.MAGENTA entitySupplyStrategy = EntitySupplyStrategy.cacheWithCachingRestFallback + permissions(Permissions.NONE) } mentionEmbed { @@ -73,15 +75,6 @@ suspend fun main(args: Array) { } } - permissions { - val permissionsService = discord.getInjectionObjects(PermissionsService::class) - val permission = command.requiredPermissionLevel - if (guild != null) - permissionsService.hasClearance(guild!!, user, permission) - else - return@permissions command.requiredPermissionLevel == PermissionLevel.Everyone - } - onStart { val (muteService, banService, cacheService) = this.getInjectionObjects( MuteService::class, diff --git a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt index 1d8d25f..002f73d 100644 --- a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt +++ b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt @@ -1,7 +1,6 @@ package me.ddivad.judgebot.arguments import dev.kord.core.entity.Member -import me.ddivad.judgebot.services.PermissionsService import me.jakejmattson.discordkt.api.arguments.* import me.jakejmattson.discordkt.api.dsl.CommandEvent import me.jakejmattson.discordkt.api.extensions.toSnowflakeOrNull @@ -14,20 +13,17 @@ open class LowerMemberArg(override val name: String = "LowerMemberArg") : Argume override suspend fun generateExamples(event: CommandEvent<*>) = mutableListOf("@User", "197780697866305536", "302134543639511050") override suspend fun convert(arg: String, args: List, event: CommandEvent<*>): ArgumentResult { - val permissionsService = event.discord.getInjectionObjects(PermissionsService::class) val guild = event.guild ?: return Error("No guild found") val member = arg.toSnowflakeOrNull()?.let { guild.getMemberOrNull(it) } ?: return Error("Not found") + val author = event.author.asMember(event.guild!!.id) return when { - event.author.asMember(event.guild!!.id).isHigherRankedThan(permissionsService, member) -> + event.discord.permissions.isHigherLevel(event.discord, author, member) -> Error("You don't have the permission to use this command on the target user.") else -> Success(member) } } override fun formatData(data: Member) = "@${data.tag}" -} - -suspend fun Member.isHigherRankedThan(permissions: PermissionsService, targetMember: Member) = - permissions.getPermissionRank(this) < permissions.getPermissionRank(targetMember) +} \ No newline at end of file diff --git a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt index 2aa592c..3e47abd 100644 --- a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt +++ b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt @@ -1,7 +1,6 @@ package me.ddivad.judgebot.arguments import dev.kord.core.entity.User -import me.ddivad.judgebot.services.PermissionsService import me.jakejmattson.discordkt.api.arguments.* import me.jakejmattson.discordkt.api.dsl.CommandEvent import me.jakejmattson.discordkt.api.extensions.toSnowflakeOrNull @@ -14,15 +13,15 @@ open class LowerUserArg(override val name: String = "LowerUserArg") : ArgumentTy override suspend fun generateExamples(event: CommandEvent<*>) = mutableListOf("@User", "197780697866305536", "302134543639511050") override suspend fun convert(arg: String, args: List, event: CommandEvent<*>): ArgumentResult { - val permissionsService = event.discord.getInjectionObjects(PermissionsService::class) val guild = event.guild ?: return Error("No guild found") val user = arg.toSnowflakeOrNull()?.let { guild.kord.getUser(it) } ?: return Error("User Not Found") val member = guild.getMemberOrNull(user.id) ?: return Success(user) + val author = event.author.asMember(event.guild!!.id) return when { - event.author.asMember(event.guild!!.id).isHigherRankedThan(permissionsService, member) -> - Error("You don't have the permission to use this command on the target user") + event.discord.permissions.isHigherLevel(event.discord, author, member) -> + Error("You don't have the permission to use this command on the target user.") else -> Success(member.asUser()) } } diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/GuildCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/GuildCommands.kt index 8c4ac79..f7e1ba2 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/GuildCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/GuildCommands.kt @@ -4,11 +4,10 @@ import me.ddivad.judgebot.arguments.GuildConfigArg import me.ddivad.judgebot.conversations.guild.GuildSetupConversation import me.ddivad.judgebot.conversations.guild.EditConfigConversation import me.ddivad.judgebot.dataclasses.Configuration +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.embeds.createActivePunishmentsEmbed import me.ddivad.judgebot.services.DatabaseService import me.ddivad.judgebot.services.infractions.MuteService -import me.ddivad.judgebot.services.PermissionLevel -import me.ddivad.judgebot.services.requiredPermissionLevel import me.jakejmattson.discordkt.api.dsl.commands fun guildConfigCommands(configuration: Configuration, @@ -16,7 +15,7 @@ fun guildConfigCommands(configuration: Configuration, muteService: MuteService) = commands("Guild") { guildCommand("setup") { description = "Configure a guild to use Judgebot." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute { if (configuration.hasGuildConfig(guild.id.value)) { respond("Guild configuration exists. To modify it use the commands to set values.") @@ -32,7 +31,7 @@ fun guildConfigCommands(configuration: Configuration, guildCommand("configuration") { description = "Update configuration parameters for this guild (conversation)." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(GuildConfigArg.optional("options")) { if (!configuration.hasGuildConfig(guild.id.value)) { respond("Please run the **setup** command to set this initially.") @@ -46,7 +45,7 @@ fun guildConfigCommands(configuration: Configuration, guildCommand("activePunishments") { description = "View active punishments for a guild." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute { val punishments = databaseService.guilds.getActivePunishments(guild) if (punishments.isEmpty()) { diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/InfoCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/InfoCommands.kt index a7f6db9..10a59e0 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/InfoCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/InfoCommands.kt @@ -5,16 +5,12 @@ import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction import me.ddivad.judgebot.arguments.LowerMemberArg import me.ddivad.judgebot.dataclasses.Info +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.embeds.createInformationEmbed import me.ddivad.judgebot.extensions.testDmStatus import me.ddivad.judgebot.services.DatabaseService -import me.ddivad.judgebot.services.HelpService -import me.ddivad.judgebot.services.PermissionLevel -import me.ddivad.judgebot.services.requiredPermissionLevel -import me.jakejmattson.discordkt.api.arguments.CommandArg import me.jakejmattson.discordkt.api.arguments.EveryArg import me.jakejmattson.discordkt.api.arguments.IntegerArg -import me.jakejmattson.discordkt.api.arguments.UnicodeEmojiArg import me.jakejmattson.discordkt.api.dsl.commands import me.jakejmattson.discordkt.api.extensions.sendPrivateMessage @@ -22,7 +18,7 @@ import me.jakejmattson.discordkt.api.extensions.sendPrivateMessage fun createInformationCommands(databaseService: DatabaseService) = commands("Information") { guildCommand("info") { description = "Send an information message to a guild member" - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg, EveryArg("Info Content")) { val (target, content) = args try { @@ -45,7 +41,7 @@ fun createInformationCommands(databaseService: DatabaseService) = commands("Info guildCommand("removeInfo") { description = "Remove an information message from a member record." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(LowerMemberArg, IntegerArg("Info ID")) { val (target, id) = args val user = databaseService.users.getOrCreateUser(target, guild) diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/InfractionCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/InfractionCommands.kt index a146fef..595bdbd 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/InfractionCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/InfractionCommands.kt @@ -1,8 +1,8 @@ package me.ddivad.judgebot.commands -import dev.kord.common.entity.Permission import me.ddivad.judgebot.arguments.LowerUserArg import dev.kord.common.exception.RequestException +import dev.kord.core.behavior.reply import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction import me.ddivad.judgebot.arguments.LowerMemberArg @@ -10,16 +10,16 @@ import me.ddivad.judgebot.conversations.InfractionConversation import me.ddivad.judgebot.dataclasses.Configuration import me.ddivad.judgebot.dataclasses.Infraction import me.ddivad.judgebot.dataclasses.InfractionType +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.extensions.testDmStatus import me.ddivad.judgebot.services.* -import me.ddivad.judgebot.extensions.* import me.ddivad.judgebot.services.infractions.BadPfpService import me.ddivad.judgebot.services.infractions.BadnameService import me.ddivad.judgebot.services.infractions.InfractionService import me.jakejmattson.discordkt.api.arguments.BooleanArg import me.jakejmattson.discordkt.api.arguments.EveryArg import me.jakejmattson.discordkt.api.arguments.IntegerArg -import me.jakejmattson.discordkt.api.arguments.UserArg +import me.jakejmattson.discordkt.api.conversations.ConversationResult import me.jakejmattson.discordkt.api.dsl.commands @Suppress("unused") @@ -30,7 +30,7 @@ fun createInfractionCommands(databaseService: DatabaseService, badnameService: BadnameService) = commands("Infraction") { guildCommand("strike", "s", "S") { description = "Strike a user." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(LowerMemberArg, IntegerArg("Weight").optional(1), EveryArg("Reason")) { val (targetMember, weight, reason) = args val guildConfiguration = config[guild.id.value] ?: return@execute @@ -46,15 +46,20 @@ fun createInfractionCommands(databaseService: DatabaseService, this.message.addReaction(Emojis.x) respond("${targetMember.mention} has DMs disabled. No messages will be sent.") } - InfractionConversation(databaseService, config, infractionService) + val conversationResult = InfractionConversation(databaseService, config, infractionService) .createInfractionConversation(guild, targetMember, weight, reason, InfractionType.Strike) .startPublicly(discord, author, channel) + if (conversationResult == ConversationResult.HAS_CONVERSATION) { + message.reply { content = "You already have an active Strike conversation. Make sure you selected a rule." } + } else if (conversationResult == ConversationResult.EXITED) { + message.reply { content = "Infraction cancelled." } + } } } guildCommand("warn", "w", "W") { description = "Warn a user." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg, EveryArg("Reason")) { val (targetMember, reason) = args try { @@ -72,7 +77,7 @@ fun createInfractionCommands(databaseService: DatabaseService, guildCommand("badpfp") { description = "Notifies the user that they should change their profile pic and applies a 30 minute mute. Bans the user if they don't change picture." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(BooleanArg("cancel", "apply", "cancel").optional(true), LowerMemberArg) { val (cancel, targetMember) = args try { @@ -103,7 +108,7 @@ fun createInfractionCommands(databaseService: DatabaseService, guildCommand("badname") { description = "Rename a guild member that has a bad name." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg) { badnameService.chooseRandomNickname(args.first) respond("User renamed to ${args.first.mention}") @@ -112,7 +117,7 @@ fun createInfractionCommands(databaseService: DatabaseService, guildCommand("cleanseInfractions") { description = "Use this to delete (permanently) as user's infractions." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute(LowerUserArg) { val user = databaseService.users.getOrCreateUser(args.first, guild) if (user.getGuildInfo(guild.id.asString).infractions.isEmpty()) { @@ -126,7 +131,7 @@ fun createInfractionCommands(databaseService: DatabaseService, guildCommand("removeInfraction") { description = "Use this to delete (permanently) an infraction from a user." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute(LowerUserArg, IntegerArg("Infraction ID")) { val user = databaseService.users.getOrCreateUser(args.first, guild) if (user.getGuildInfo(guild.id.asString).infractions.isEmpty()) { diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/MuteCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/MuteCommands.kt index 49de484..e8000fe 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/MuteCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/MuteCommands.kt @@ -4,8 +4,8 @@ import dev.kord.common.exception.RequestException import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction import me.ddivad.judgebot.arguments.LowerMemberArg +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.extensions.testDmStatus -import me.ddivad.judgebot.services.* import me.ddivad.judgebot.services.infractions.MuteService import me.ddivad.judgebot.services.infractions.RoleState import me.ddivad.judgebot.util.timeToString @@ -18,7 +18,7 @@ import kotlin.math.roundToLong fun createMuteCommands(muteService: MuteService) = commands("Mute") { guildCommand("mute") { description = "Mute a user for a specified time." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg, TimeArg("Time"), EveryArg("Reason")) { val (targetMember, length, reason) = args try { @@ -35,7 +35,7 @@ fun createMuteCommands(muteService: MuteService) = commands("Mute") { guildCommand("unmute") { description = "Unmute a user." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg) { val targetMember = args.first if (muteService.checkRoleState(guild, targetMember) == RoleState.None) { @@ -50,7 +50,7 @@ fun createMuteCommands(muteService: MuteService) = commands("Mute") { guildCommand("gag") { description = "Mute a user for 5 minutes while you deal with something" - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(LowerMemberArg) { val targetMember = args.first if (muteService.checkRoleState(guild, targetMember) == RoleState.Tracked) { diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/NoteCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/NoteCommands.kt index fa69b0a..db1822e 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/NoteCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/NoteCommands.kt @@ -1,9 +1,8 @@ package me.ddivad.judgebot.commands import me.ddivad.judgebot.arguments.LowerMemberArg +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.services.DatabaseService -import me.ddivad.judgebot.services.PermissionLevel -import me.ddivad.judgebot.services.requiredPermissionLevel import me.jakejmattson.discordkt.api.arguments.EveryArg import me.jakejmattson.discordkt.api.arguments.IntegerArg import me.jakejmattson.discordkt.api.arguments.UserArg @@ -13,7 +12,7 @@ import me.jakejmattson.discordkt.api.dsl.commands fun noteCommands(databaseService: DatabaseService) = commands("Note") { guildCommand("note") { description = "Use this to add a note to a user." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(UserArg, EveryArg("Note Content")) { val (target, note) = args val user = databaseService.users.getOrCreateUser(target, guild) @@ -24,7 +23,7 @@ fun noteCommands(databaseService: DatabaseService) = commands("Note") { guildCommand("editNote") { description = "Use this to edit a note." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(UserArg, IntegerArg("Note to edit"), EveryArg("Note Content")) { val (target, noteId, note) = args val user = databaseService.users.getOrCreateUser(target, guild) @@ -39,7 +38,7 @@ fun noteCommands(databaseService: DatabaseService) = commands("Note") { guildCommand("deleteNote") { description = "Use this to add a delete a note from a user." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(LowerMemberArg, IntegerArg("Note ID")) { val (target, noteId) = args val user = databaseService.users.getOrCreateUser(target, guild) @@ -54,7 +53,7 @@ fun noteCommands(databaseService: DatabaseService) = commands("Note") { guildCommand("cleanseNotes") { description = "Use this to delete (permanently) as user's notes." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute(LowerMemberArg) { val target = args.first val user = databaseService.users.getOrCreateUser(target, guild) diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/RuleCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/RuleCommands.kt index 839be9d..b97f9cd 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/RuleCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/RuleCommands.kt @@ -6,12 +6,11 @@ import me.ddivad.judgebot.conversations.rules.AddRuleConversation import me.ddivad.judgebot.conversations.rules.ArchiveRuleConversation import me.ddivad.judgebot.conversations.rules.EditRuleConversation import me.ddivad.judgebot.dataclasses.Configuration +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.embeds.createRuleEmbed import me.ddivad.judgebot.embeds.createRulesEmbed import me.ddivad.judgebot.embeds.createRulesEmbedDetailed import me.ddivad.judgebot.services.DatabaseService -import me.ddivad.judgebot.services.PermissionLevel -import me.ddivad.judgebot.services.requiredPermissionLevel import me.jakejmattson.discordkt.api.arguments.MessageArg import me.jakejmattson.discordkt.api.dsl.commands import me.jakejmattson.discordkt.api.extensions.jumpLink @@ -22,7 +21,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("addRule") { description = "Add a rule to this guild." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute { AddRuleConversation(databaseService) .createAddRuleConversation(guild) @@ -32,7 +31,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("editRule") { description = "Edit a rule in this guild." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute { EditRuleConversation(databaseService) .createAddRuleConversation(guild) @@ -42,7 +41,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("archiveRule") { description = "Archive a rule in this guild." - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.ADMINISTRATOR execute { ArchiveRuleConversation(databaseService) .createArchiveRuleConversation(guild) @@ -52,7 +51,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("rules") { description = "List the rules of this guild. Pass a message ID to edit existing rules embed." - requiredPermissionLevel = PermissionLevel.Everyone + requiredPermission = Permissions.NONE execute(MessageArg.optionalNullable(null)) { val messageToEdit = args.first if (messageToEdit != null) { @@ -68,7 +67,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("longRules") { description = "List the rules (with descriptions) of this guild. Pass a message ID to edit existing rules embed." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(MessageArg.optionalNullable(null)) { val messageToEdit = args.first if (messageToEdit != null) { @@ -84,7 +83,7 @@ fun ruleCommands(configuration: Configuration, guildCommand("rule") { description = "List a rule from this guild." - requiredPermissionLevel = PermissionLevel.Everyone + requiredPermission = Permissions.NONE execute(RuleArg) { val rule = databaseService.guilds.getRule(guild, args.first.number)!! respond { diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/UserCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/UserCommands.kt index 5de7108..1d45566 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/UserCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/UserCommands.kt @@ -5,24 +5,19 @@ import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction import kotlinx.coroutines.flow.toList import me.ddivad.judgebot.arguments.LowerUserArg -import me.ddivad.judgebot.conversations.InfractionConversation import me.ddivad.judgebot.conversations.ResetUserConversation import me.ddivad.judgebot.conversations.guildChoiceConversation import me.ddivad.judgebot.dataclasses.* import me.ddivad.judgebot.embeds.createHistoryEmbed -import me.ddivad.judgebot.embeds.createCondensedHistoryEmbed import me.ddivad.judgebot.embeds.createLinkedAccountMenu import me.ddivad.judgebot.embeds.createSelfHistoryEmbed import me.ddivad.judgebot.services.DatabaseService import me.ddivad.judgebot.services.LoggingService -import me.ddivad.judgebot.services.PermissionLevel import me.ddivad.judgebot.services.infractions.BanService -import me.ddivad.judgebot.services.requiredPermissionLevel import me.jakejmattson.discordkt.api.arguments.* import me.jakejmattson.discordkt.api.dsl.commands import me.jakejmattson.discordkt.api.extensions.mutualGuilds import me.jakejmattson.discordkt.api.extensions.sendPrivateMessage -import me.jakejmattson.discordkt.api.extensions.toSnowflake import java.awt.Color @Suppress("unused") @@ -34,7 +29,7 @@ fun createUserCommands( ) = commands("User") { guildCommand("history", "h", "H") { description = "Use this to view a user's record." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(UserArg) { val user = databaseService.users.getOrCreateUser(args.first, guild) databaseService.users.incrementUserHistory(user, guild) @@ -47,7 +42,7 @@ fun createUserCommands( guildCommand("alts") { description = "Use this to view a user's alt accounts." - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(UserArg) { val target = args.first val user = databaseService.users.getOrCreateUser(args.first, guild) @@ -67,7 +62,7 @@ fun createUserCommands( guildCommand("whatpfp") { description = "Perform a reverse image search of a User's profile picture" - requiredPermissionLevel = PermissionLevel.Moderator + requiredPermission = Permissions.MODERATOR execute(UserArg) { val user = args.first val reverseSearchUrl = "" @@ -82,7 +77,7 @@ fun createUserCommands( guildCommand("ban") { description = "Ban a member from this guild." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(LowerUserArg, IntegerArg("Delete message days").optional(0), EveryArg) { val (target, deleteDays, reason) = args val ban = Punishment(target.id.asString, InfractionType.Ban, reason, author.id.asString) @@ -95,7 +90,7 @@ fun createUserCommands( guildCommand("unban") { description = "Unban a banned member from this guild." - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(UserArg) { val user = args.first guild.getBanOrNull(user.id)?.let { @@ -109,7 +104,7 @@ fun createUserCommands( guildCommand("setBanReason") { description = "Set a ban reason for a banned user" - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(UserArg, EveryArg("Reason")) { val (user, reason) = args val ban = Ban(user.id.asString, author.id.asString, reason) @@ -127,7 +122,7 @@ fun createUserCommands( guildCommand("getBanReason") { description = "Get a ban reason for a banned user" - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(UserArg) { val user = args.first guild.getBanOrNull(user.id)?.let { @@ -141,7 +136,7 @@ fun createUserCommands( command("selfHistory") { description = "View your infraction history (contents will be DM'd)" - requiredPermissionLevel = PermissionLevel.Everyone + requiredPermission = Permissions.NONE execute { val user = author val mutualGuilds = author.mutualGuilds.toList().filter { config[it.id.value] != null } @@ -162,7 +157,7 @@ fun createUserCommands( guildCommand("link") { description = "Link a user's alt account with their main" - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(UserArg("Main Account"), UserArg("Alt Account")) { val (main, alt) = args val mainRecord = databaseService.users.getOrCreateUser(main, guild) @@ -175,7 +170,7 @@ fun createUserCommands( guildCommand("unlink") { description = "Link a user's alt account with their main" - requiredPermissionLevel = PermissionLevel.Staff + requiredPermission = Permissions.STAFF execute(UserArg("Main Account"), UserArg("Alt Account")) { val (main, alt) = args val mainRecord = databaseService.users.getOrCreateUser(main, guild) @@ -188,7 +183,7 @@ fun createUserCommands( guildCommand("reset") { description = "Reset a user's record, and any linked accounts" - requiredPermissionLevel = PermissionLevel.Administrator + requiredPermission = Permissions.STAFF execute(LowerUserArg) { val target = args.first ResetUserConversation(databaseService, config) diff --git a/src/main/kotlin/me/ddivad/judgebot/commands/UtilityCommands.kt b/src/main/kotlin/me/ddivad/judgebot/commands/UtilityCommands.kt index 1b837f7..b853eb4 100644 --- a/src/main/kotlin/me/ddivad/judgebot/commands/UtilityCommands.kt +++ b/src/main/kotlin/me/ddivad/judgebot/commands/UtilityCommands.kt @@ -1,5 +1,6 @@ package me.ddivad.judgebot.commands +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.services.HelpService import me.jakejmattson.discordkt.api.arguments.AnyArg import me.jakejmattson.discordkt.api.arguments.CommandArg @@ -9,6 +10,7 @@ import me.jakejmattson.discordkt.api.dsl.commands fun createInformationCommands(helpService: HelpService) = commands("Utility") { command("help") { description = "Display help information." + requiredPermission = Permissions.NONE execute(AnyArg("Command").optional("")) { val input = args.first if (input == "") { diff --git a/src/main/kotlin/me/ddivad/judgebot/dataclasses/Permissions.kt b/src/main/kotlin/me/ddivad/judgebot/dataclasses/Permissions.kt new file mode 100644 index 0000000..ea3d346 --- /dev/null +++ b/src/main/kotlin/me/ddivad/judgebot/dataclasses/Permissions.kt @@ -0,0 +1,48 @@ +package me.ddivad.judgebot.dataclasses + +import dev.kord.common.entity.Permission +import dev.kord.core.any +import me.jakejmattson.discordkt.api.dsl.PermissionContext +import me.jakejmattson.discordkt.api.dsl.PermissionSet + +enum class Permissions : PermissionSet { + BOT_OWNER { + override suspend fun hasPermission(context: PermissionContext) = + context.discord.getInjectionObjects().ownerId == context.user.id.asString + }, + GUILD_OWNER { + override suspend fun hasPermission(context: PermissionContext) = + context.getMember()?.isOwner() ?: false + + }, + ADMINISTRATOR { + override suspend fun hasPermission(context: PermissionContext): Boolean { + val guild = context.guild ?: return false + val member = context.user.asMember(guild.id) + val configuration = context.discord.getInjectionObjects() + return member.roles.any { configuration[guild.id.value]!!.adminRoles.contains(it.id.asString) } || member.getPermissions() + .contains( + Permission.Administrator + ) + } + }, + STAFF { + override suspend fun hasPermission(context: PermissionContext): Boolean { + val guild = context.guild ?: return false + val member = context.user.asMember(guild.id) + val configuration = context.discord.getInjectionObjects() + return member.roles.any { configuration[guild.id.value]!!.staffRoles.contains(it.id.asString) } + } + }, + MODERATOR { + override suspend fun hasPermission(context: PermissionContext): Boolean { + val guild = context.guild ?: return false + val member = context.user.asMember(guild.id) + val configuration = context.discord.getInjectionObjects() + return member.roles.any { configuration[guild.id.value]!!.moderatorRoles.contains(it.id.asString) } + } + }, + NONE { + override suspend fun hasPermission(context: PermissionContext) = true + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt b/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt index 5ca3884..9aee2ef 100644 --- a/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt +++ b/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt @@ -12,26 +12,27 @@ import me.jakejmattson.discordkt.api.extensions.toSnowflake @Suppress("unused") fun onMemberReactionAdd(configuration: Configuration) = listeners { - on { - val guild = guild?.asGuildOrNull() ?: return@on - val guildConfiguration = configuration[guild.asGuild().id.value] - if (!guildConfiguration?.reactions!!.enabled) return@on - - when (this.emoji.name) { - guildConfiguration.reactions.flagMessageReaction -> { - message.deleteReaction(this.emoji) - guild.asGuild() - .getChannelOf(guildConfiguration.loggingConfiguration.alertChannel.toSnowflake()) - .asChannel() - .createMessage( - "**Message Flagged**" + - "\n**User**: ${user.mention}" + - "\n**Channel**: ${message.channel.mention}" + - "\n**Author:** ${message.asMessage().author?.mention}" + - "\n**Message:** ${message.asMessage().jumpLink()}" - ) - .addReaction(Emojis.question) - } - } - } +// on { +// println(emoji.name + " added") +// val guild = guild?.asGuildOrNull() ?: return@on +// val guildConfiguration = configuration[guild.asGuild().id.value] +// if (!guildConfiguration?.reactions!!.enabled) return@on +// +// when (this.emoji.name) { +// guildConfiguration.reactions.flagMessageReaction -> { +// message.deleteReaction(this.emoji) +// guild.asGuild() +// .getChannelOf(guildConfiguration.loggingConfiguration.alertChannel.toSnowflake()) +// .asChannel() +// .createMessage( +// "**Message Flagged**" + +// "\n**User**: ${user.mention}" + +// "\n**Channel**: ${message.channel.mention}" + +// "\n**Author:** ${message.asMessage().author?.mention}" + +// "\n**Message:** ${message.asMessage().jumpLink()}" +// ) +// .addReaction(Emojis.question) +// } +// } +// } } diff --git a/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt b/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt index 369ed7b..06ee0f7 100644 --- a/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt +++ b/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt @@ -4,14 +4,11 @@ import dev.kord.common.exception.RequestException import dev.kord.core.event.message.ReactionAddEvent import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction -import me.ddivad.judgebot.arguments.isHigherRankedThan import me.ddivad.judgebot.dataclasses.Configuration import me.ddivad.judgebot.embeds.createMessageDeleteEmbed import me.ddivad.judgebot.embeds.createCondensedHistoryEmbed import me.ddivad.judgebot.services.DatabaseService import me.ddivad.judgebot.services.LoggingService -import me.ddivad.judgebot.services.PermissionLevel -import me.ddivad.judgebot.services.PermissionsService import me.ddivad.judgebot.services.infractions.MuteService import me.ddivad.judgebot.services.infractions.RoleState import me.jakejmattson.discordkt.api.dsl.listeners @@ -22,72 +19,68 @@ import me.jakejmattson.discordkt.api.extensions.sendPrivateMessage fun onStaffReactionAdd( muteService: MuteService, databaseService: DatabaseService, - permissionsService: PermissionsService, loggingService: LoggingService, configuration: Configuration ) = listeners { on { - val guild = guild?.asGuildOrNull() ?: return@on - val guildConfiguration = configuration[guild.asGuild().id.value] - if (!guildConfiguration?.reactions!!.enabled) return@on - val staffMember = user.asMemberOrNull(guild.id) ?: return@on - val messageAuthor = message.asMessage().author?.asMemberOrNull(guild.id) ?: return@on - val msg = message.asMessage() - - if (permissionsService.hasPermission(staffMember, PermissionLevel.Moderator) && !staffMember.isHigherRankedThan( - permissionsService, - messageAuthor - ) - ) { - when (this.emoji.name) { - guildConfiguration.reactions.gagReaction -> { - msg.deleteReaction(this.emoji) - if (muteService.checkRoleState(guild, messageAuthor) == RoleState.Tracked) { - staffMember.sendPrivateMessage("${messageAuthor.mention} is already muted.") - return@on - } - muteService.gag(guild, messageAuthor, staffMember) - staffMember.sendPrivateMessage("${messageAuthor.mention} gagged.") - loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) - } - guildConfiguration.reactions.historyReaction -> { - msg.deleteReaction(this.emoji) - staffMember.sendPrivateMessage { - createCondensedHistoryEmbed( - messageAuthor, - databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), - guild.asGuild(), - configuration - ) - } - loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) - } - guildConfiguration.reactions.deleteMessageReaction -> { - msg.deleteReaction(this.emoji) - msg.delete() - databaseService.users.addMessageDelete( - guild, - databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), - true - ) - try { - messageAuthor.sendPrivateMessage { - createMessageDeleteEmbed(guild, msg) - } - } catch (ex: RequestException) { - staffMember.sendPrivateMessage( - "User ${messageAuthor.mention} has DM's disabled." + - " Message deleted without notification." - ) - } - loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) - } - Emojis.question.unicode -> { - if (this.user.isSelf() || msg.author != this.message.kord.getSelf()) return@on - msg.deleteReaction(this.emoji) - msg.addReaction(Emojis.whiteCheckMark) - } - } - } + println("listener") +// val guild = guild?.asGuildOrNull() ?: return@on +// val guildConfiguration = configuration[guild.asGuild().id.value] +// if (!guildConfiguration?.reactions!!.enabled) return@on +// val staffMember = user.asMemberOrNull(guild.id) ?: return@on +// val messageAuthor = message.asMessage().author?.asMemberOrNull(guild.id) ?: return@on +// val msg = message.asMessage() +// println(discord.permissions.isHigherLevel(discord, staffMember, messageAuthor)) +// if (discord.permissions.isHigherLevel(discord, staffMember, messageAuthor)) { +// when (this.emoji.name) { +// guildConfiguration.reactions.gagReaction -> { +// msg.deleteReaction(this.emoji) +// if (muteService.checkRoleState(guild, messageAuthor) == RoleState.Tracked) { +// staffMember.sendPrivateMessage("${messageAuthor.mention} is already muted.") +// return@on +// } +// muteService.gag(guild, messageAuthor, staffMember) +// staffMember.sendPrivateMessage("${messageAuthor.mention} gagged.") +// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) +// } +// guildConfiguration.reactions.historyReaction -> { +// msg.deleteReaction(this.emoji) +// staffMember.sendPrivateMessage { +// createCondensedHistoryEmbed( +// messageAuthor, +// databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), +// guild.asGuild(), +// configuration +// ) +// } +// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) +// } +// guildConfiguration.reactions.deleteMessageReaction -> { +// msg.deleteReaction(this.emoji) +// msg.delete() +// databaseService.users.addMessageDelete( +// guild, +// databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), +// true +// ) +// try { +// messageAuthor.sendPrivateMessage { +// createMessageDeleteEmbed(guild, msg) +// } +// } catch (ex: RequestException) { +// staffMember.sendPrivateMessage( +// "User ${messageAuthor.mention} has DM's disabled." + +// " Message deleted without notification." +// ) +// } +// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) +// } +// Emojis.question.unicode -> { +// if (this.user.isSelf() || msg.author != this.message.kord.getSelf()) return@on +// msg.deleteReaction(this.emoji) +// msg.addReaction(Emojis.whiteCheckMark) +// } +// } +// } } } diff --git a/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt b/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt index 94914f1..f44b528 100644 --- a/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt +++ b/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt @@ -7,6 +7,7 @@ import dev.kord.core.entity.User import dev.kord.x.emoji.DiscordEmoji import dev.kord.x.emoji.Emojis import kotlinx.coroutines.runBlocking +import me.jakejmattson.discordkt.api.Discord import me.jakejmattson.discordkt.api.annotations.Service import me.jakejmattson.discordkt.api.arguments.ArgumentType import me.jakejmattson.discordkt.api.arguments.OptionalArg @@ -15,23 +16,20 @@ import me.jakejmattson.discordkt.api.dsl.CommandEvent import me.jakejmattson.discordkt.api.dsl.Execution @Service -class HelpService(private val permissionsService: PermissionsService) { - private suspend fun Command.isVisible(guild: Guild, user: User) = - permissionsService.isCommandVisible(guild, user, this) - +class HelpService(private val discord: Discord) { suspend fun buildHelpEmbed(event: CommandEvent<*>) = event.respondMenu { val container = event.discord.commands fun joinNames(value: List) = value.joinToString("\n") { it.names.first() } val groupedCommands = container - .filter { it.isVisible(event.guild!!, event.author) } + .filter { it.hasPermissionToRun(event) } .groupBy { it.category } .toList() .sortedByDescending { it.second.size } val categoryNames = container - .filter { it.isVisible(event.guild!!, event.author) } + .filter { it.hasPermissionToRun(event) } .groupBy { it.category } .toList() .sortedByDescending { it.second.size } diff --git a/src/main/kotlin/me/ddivad/judgebot/services/PermissionsService.kt b/src/main/kotlin/me/ddivad/judgebot/services/PermissionsService.kt deleted file mode 100644 index b223aae..0000000 --- a/src/main/kotlin/me/ddivad/judgebot/services/PermissionsService.kt +++ /dev/null @@ -1,61 +0,0 @@ -package me.ddivad.judgebot.services - -import dev.kord.core.any -import dev.kord.core.entity.Guild -import dev.kord.core.entity.Member -import dev.kord.core.entity.User -import me.ddivad.judgebot.dataclasses.Configuration -import me.jakejmattson.discordkt.api.annotations.Service -import me.jakejmattson.discordkt.api.dsl.Command - -enum class PermissionLevel { - Everyone, - Moderator, - Staff, - Administrator, - GuildOwner, - BotOwner -} - -val DEFAULT_REQUIRED_PERMISSION = PermissionLevel.Everyone -val commandPermissions: MutableMap = mutableMapOf() - -@Service -class PermissionsService(private val configuration: Configuration) { - suspend fun hasClearance(guild: Guild?, user: User, requiredPermissionLevel: PermissionLevel): Boolean { - val permissionLevel = guild?.getMember(user.id)?.let { getPermissionLevel(it) } - return if (permissionLevel == null) { - requiredPermissionLevel == PermissionLevel.Everyone || user.id.asString == configuration.ownerId - } else { - permissionLevel >= requiredPermissionLevel - } - } - - suspend fun hasPermission(member: Member, level: PermissionLevel) = getPermissionLevel(member) >= level - suspend fun getPermissionRank(member: Member) = getPermissionLevel(member).ordinal - - private suspend fun getPermissionLevel(member: Member) = - when { - member.isBotOwner() -> PermissionLevel.BotOwner - member.isGuildOwner() -> PermissionLevel.GuildOwner - member.isAdministrator() -> PermissionLevel.Administrator - member.isStaff() -> PermissionLevel.Staff - member.isModerator() -> PermissionLevel.Moderator - else -> PermissionLevel.Everyone - } - - private fun Member.isBotOwner() = id.asString == configuration.ownerId - private suspend fun Member.isGuildOwner() = isOwner() - private suspend fun Member.isAdministrator() = roles.any { configuration[guild.id.value]!!.adminRoles.contains(it.id.asString) } - private suspend fun Member.isStaff() = roles.any { configuration[guild.id.value]!!.staffRoles.contains(it.id.asString) } - private suspend fun Member.isModerator() = roles.any { configuration[guild.id.value]!!.moderatorRoles.contains(it.id.asString) } - - suspend fun isCommandVisible(guild: Guild, user: User, command: Command) = - hasClearance(guild, user, command.requiredPermissionLevel) -} - -var Command.requiredPermissionLevel: PermissionLevel - get() = commandPermissions[this] ?: DEFAULT_REQUIRED_PERMISSION - set(value) { - commandPermissions[this] = value - } \ No newline at end of file From e7dbb0b13c3f54f4f5f80b2042939e2441039aae Mon Sep 17 00:00:00 2001 From: ddivad195 Date: Wed, 4 Aug 2021 19:47:42 +0100 Subject: [PATCH 2/6] feat: implement various changes and updates --- src/main/kotlin/me/ddivad/judgebot/Main.kt | 7 ++ .../judgebot/arguments/LowerMemberArg.kt | 2 +- .../ddivad/judgebot/arguments/LowerUserArg.kt | 2 +- .../judgebot/dataclasses/GuildMember.kt | 3 +- .../judgebot/listeners/JoinLeaveListener.kt | 8 -- .../listeners/MemberReactionListeners.kt | 45 ++++--- .../listeners/StaffReactionListeners.kt | 119 +++++++++--------- .../services/database/UserOperations.kt | 2 +- 8 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/main/kotlin/me/ddivad/judgebot/Main.kt b/src/main/kotlin/me/ddivad/judgebot/Main.kt index a51afba..20f3987 100644 --- a/src/main/kotlin/me/ddivad/judgebot/Main.kt +++ b/src/main/kotlin/me/ddivad/judgebot/Main.kt @@ -33,6 +33,13 @@ suspend fun main(args: Array) { theme = Color.MAGENTA entitySupplyStrategy = EntitySupplyStrategy.cacheWithCachingRestFallback permissions(Permissions.NONE) + intents = Intents( + Intent.GuildMembers, + Intent.DirectMessages, + Intent.GuildBans, + Intent.Guilds, + Intent.GuildMessageReactions + ) } mentionEmbed { diff --git a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt index 002f73d..da78ede 100644 --- a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt +++ b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerMemberArg.kt @@ -19,7 +19,7 @@ open class LowerMemberArg(override val name: String = "LowerMemberArg") : Argume val author = event.author.asMember(event.guild!!.id) return when { - event.discord.permissions.isHigherLevel(event.discord, author, member) -> + event.discord.permissions.isHigherLevel(event.discord, member, author) -> Error("You don't have the permission to use this command on the target user.") else -> Success(member) } diff --git a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt index 3e47abd..3349fb1 100644 --- a/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt +++ b/src/main/kotlin/me/ddivad/judgebot/arguments/LowerUserArg.kt @@ -20,7 +20,7 @@ open class LowerUserArg(override val name: String = "LowerUserArg") : ArgumentTy val author = event.author.asMember(event.guild!!.id) return when { - event.discord.permissions.isHigherLevel(event.discord, author, member) -> + event.discord.permissions.isHigherLevel(event.discord, member, author) -> Error("You don't have the permission to use this command on the target user.") else -> Success(member.asUser()) } diff --git a/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt b/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt index 909cfb1..881639b 100644 --- a/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt +++ b/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt @@ -99,6 +99,7 @@ data class GuildMember( infraction.id = nextId this.infractions.add(infraction) this.points += infraction.points + this.pointDecayTimer = DateTime().millis.plus(infraction.punishment?.duration ?: 0) this.lastInfraction = DateTime().millis } @@ -112,7 +113,7 @@ data class GuildMember( } fun checkPointDecay(guild: Guild, configuration: GuildConfiguration) = with(this.getGuildInfo(guild.id.asString)) { - val weeksSincePointsDecayed = Weeks.weeksBetween(DateTime(this.pointDecayTimer), DateTime()).weeks + val weeksSincePointsDecayed = Weeks.weeksBetween(DateTime(this.pointDecayTimer), DateTime().plusWeeks(6)).weeks if (weeksSincePointsDecayed > 0) { val pointsToRemove = configuration.infractionConfiguration.pointDecayPerWeek * weeksSincePointsDecayed this.points -= pointsToRemove diff --git a/src/main/kotlin/me/ddivad/judgebot/listeners/JoinLeaveListener.kt b/src/main/kotlin/me/ddivad/judgebot/listeners/JoinLeaveListener.kt index eb6def2..345baee 100644 --- a/src/main/kotlin/me/ddivad/judgebot/listeners/JoinLeaveListener.kt +++ b/src/main/kotlin/me/ddivad/judgebot/listeners/JoinLeaveListener.kt @@ -1,23 +1,15 @@ package me.ddivad.judgebot.listeners -import dev.kord.core.event.guild.GuildCreateEvent import dev.kord.core.event.guild.MemberJoinEvent import dev.kord.core.event.guild.MemberLeaveEvent -import dev.kord.gateway.PrivilegedIntent -import dev.kord.gateway.RequestGuildMembers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import me.ddivad.judgebot.services.DatabaseService import me.jakejmattson.discordkt.api.dsl.listeners -@OptIn(PrivilegedIntent::class) @Suppress("unused") fun onGuildMemberLeave(databaseService: DatabaseService) = listeners { - on { - gateway.send(RequestGuildMembers(guildId = guild.id)) - } - on { databaseService.joinLeaves.addLeaveData(guildId.asString, user.id.asString) } diff --git a/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt b/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt index 9aee2ef..5ca3884 100644 --- a/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt +++ b/src/main/kotlin/me/ddivad/judgebot/listeners/MemberReactionListeners.kt @@ -12,27 +12,26 @@ import me.jakejmattson.discordkt.api.extensions.toSnowflake @Suppress("unused") fun onMemberReactionAdd(configuration: Configuration) = listeners { -// on { -// println(emoji.name + " added") -// val guild = guild?.asGuildOrNull() ?: return@on -// val guildConfiguration = configuration[guild.asGuild().id.value] -// if (!guildConfiguration?.reactions!!.enabled) return@on -// -// when (this.emoji.name) { -// guildConfiguration.reactions.flagMessageReaction -> { -// message.deleteReaction(this.emoji) -// guild.asGuild() -// .getChannelOf(guildConfiguration.loggingConfiguration.alertChannel.toSnowflake()) -// .asChannel() -// .createMessage( -// "**Message Flagged**" + -// "\n**User**: ${user.mention}" + -// "\n**Channel**: ${message.channel.mention}" + -// "\n**Author:** ${message.asMessage().author?.mention}" + -// "\n**Message:** ${message.asMessage().jumpLink()}" -// ) -// .addReaction(Emojis.question) -// } -// } -// } + on { + val guild = guild?.asGuildOrNull() ?: return@on + val guildConfiguration = configuration[guild.asGuild().id.value] + if (!guildConfiguration?.reactions!!.enabled) return@on + + when (this.emoji.name) { + guildConfiguration.reactions.flagMessageReaction -> { + message.deleteReaction(this.emoji) + guild.asGuild() + .getChannelOf(guildConfiguration.loggingConfiguration.alertChannel.toSnowflake()) + .asChannel() + .createMessage( + "**Message Flagged**" + + "\n**User**: ${user.mention}" + + "\n**Channel**: ${message.channel.mention}" + + "\n**Author:** ${message.asMessage().author?.mention}" + + "\n**Message:** ${message.asMessage().jumpLink()}" + ) + .addReaction(Emojis.question) + } + } + } } diff --git a/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt b/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt index 06ee0f7..7f342c4 100644 --- a/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt +++ b/src/main/kotlin/me/ddivad/judgebot/listeners/StaffReactionListeners.kt @@ -5,6 +5,7 @@ import dev.kord.core.event.message.ReactionAddEvent import dev.kord.x.emoji.Emojis import dev.kord.x.emoji.addReaction import me.ddivad.judgebot.dataclasses.Configuration +import me.ddivad.judgebot.dataclasses.Permissions import me.ddivad.judgebot.embeds.createMessageDeleteEmbed import me.ddivad.judgebot.embeds.createCondensedHistoryEmbed import me.ddivad.judgebot.services.DatabaseService @@ -23,64 +24,64 @@ fun onStaffReactionAdd( configuration: Configuration ) = listeners { on { - println("listener") -// val guild = guild?.asGuildOrNull() ?: return@on -// val guildConfiguration = configuration[guild.asGuild().id.value] -// if (!guildConfiguration?.reactions!!.enabled) return@on -// val staffMember = user.asMemberOrNull(guild.id) ?: return@on -// val messageAuthor = message.asMessage().author?.asMemberOrNull(guild.id) ?: return@on -// val msg = message.asMessage() -// println(discord.permissions.isHigherLevel(discord, staffMember, messageAuthor)) -// if (discord.permissions.isHigherLevel(discord, staffMember, messageAuthor)) { -// when (this.emoji.name) { -// guildConfiguration.reactions.gagReaction -> { -// msg.deleteReaction(this.emoji) -// if (muteService.checkRoleState(guild, messageAuthor) == RoleState.Tracked) { -// staffMember.sendPrivateMessage("${messageAuthor.mention} is already muted.") -// return@on -// } -// muteService.gag(guild, messageAuthor, staffMember) -// staffMember.sendPrivateMessage("${messageAuthor.mention} gagged.") -// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) -// } -// guildConfiguration.reactions.historyReaction -> { -// msg.deleteReaction(this.emoji) -// staffMember.sendPrivateMessage { -// createCondensedHistoryEmbed( -// messageAuthor, -// databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), -// guild.asGuild(), -// configuration -// ) -// } -// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) -// } -// guildConfiguration.reactions.deleteMessageReaction -> { -// msg.deleteReaction(this.emoji) -// msg.delete() -// databaseService.users.addMessageDelete( -// guild, -// databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), -// true -// ) -// try { -// messageAuthor.sendPrivateMessage { -// createMessageDeleteEmbed(guild, msg) -// } -// } catch (ex: RequestException) { -// staffMember.sendPrivateMessage( -// "User ${messageAuthor.mention} has DM's disabled." + -// " Message deleted without notification." -// ) -// } -// loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) -// } -// Emojis.question.unicode -> { -// if (this.user.isSelf() || msg.author != this.message.kord.getSelf()) return@on -// msg.deleteReaction(this.emoji) -// msg.addReaction(Emojis.whiteCheckMark) -// } -// } -// } + val guild = guild?.asGuildOrNull() ?: return@on + val guildConfiguration = configuration[guild.asGuild().id.value] + if (!guildConfiguration?.reactions!!.enabled) return@on + val staffMember = user.asMemberOrNull(guild.id) ?: return@on + val msg = message.asMessage() + val messageAuthor = msg.author?.asMemberOrNull(guild.id) ?: return@on + if (discord.permissions.hasPermission(discord, staffMember, Permissions.MODERATOR) + && discord.permissions.isHigherLevel(discord, staffMember, messageAuthor) + ) { + when (this.emoji.name) { + guildConfiguration.reactions.gagReaction -> { + msg.deleteReaction(this.emoji) + if (muteService.checkRoleState(guild, messageAuthor) == RoleState.Tracked) { + staffMember.sendPrivateMessage("${messageAuthor.mention} is already muted.") + return@on + } + muteService.gag(guild, messageAuthor, staffMember) + staffMember.sendPrivateMessage("${messageAuthor.mention} gagged.") + loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) + } + guildConfiguration.reactions.historyReaction -> { + msg.deleteReaction(this.emoji) + staffMember.sendPrivateMessage { + createCondensedHistoryEmbed( + messageAuthor, + databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), + guild.asGuild(), + configuration + ) + } + loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) + } + guildConfiguration.reactions.deleteMessageReaction -> { + msg.deleteReaction(this.emoji) + msg.delete() + databaseService.users.addMessageDelete( + guild, + databaseService.users.getOrCreateUser(messageAuthor, guild.asGuild()), + true + ) + try { + messageAuthor.sendPrivateMessage { + createMessageDeleteEmbed(guild, msg) + } + } catch (ex: RequestException) { + staffMember.sendPrivateMessage( + "User ${messageAuthor.mention} has DM's disabled." + + " Message deleted without notification." + ) + } + loggingService.staffReactionUsed(guild, staffMember, messageAuthor, this.emoji) + } + Emojis.question.unicode -> { + if (this.user.isSelf() || msg.author != this.message.kord.getSelf()) return@on + msg.deleteReaction(this.emoji) + msg.addReaction(Emojis.whiteCheckMark) + } + } + } } } diff --git a/src/main/kotlin/me/ddivad/judgebot/services/database/UserOperations.kt b/src/main/kotlin/me/ddivad/judgebot/services/database/UserOperations.kt index 8881b33..bcf1b25 100644 --- a/src/main/kotlin/me/ddivad/judgebot/services/database/UserOperations.kt +++ b/src/main/kotlin/me/ddivad/judgebot/services/database/UserOperations.kt @@ -86,8 +86,8 @@ class UserOperations( } suspend fun addInfraction(guild: Guild, user: GuildMember, infraction: Infraction): Infraction { - user.addInfraction(infraction, guild) infraction.punishment = getPunishmentForPoints(guild, user) + user.addInfraction(infraction, guild) this.updateUser(user) return infraction } From a3c2edf8a2bfa0550a6875df0c1b8cf26f859289 Mon Sep 17 00:00:00 2001 From: ddivad195 Date: Wed, 4 Aug 2021 19:50:55 +0100 Subject: [PATCH 3/6] fix: remove timeframe testing code --- src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt b/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt index 881639b..086a246 100644 --- a/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt +++ b/src/main/kotlin/me/ddivad/judgebot/dataclasses/GuildMember.kt @@ -113,7 +113,7 @@ data class GuildMember( } fun checkPointDecay(guild: Guild, configuration: GuildConfiguration) = with(this.getGuildInfo(guild.id.asString)) { - val weeksSincePointsDecayed = Weeks.weeksBetween(DateTime(this.pointDecayTimer), DateTime().plusWeeks(6)).weeks + val weeksSincePointsDecayed = Weeks.weeksBetween(DateTime(this.pointDecayTimer), DateTime()).weeks if (weeksSincePointsDecayed > 0) { val pointsToRemove = configuration.infractionConfiguration.pointDecayPerWeek * weeksSincePointsDecayed this.points -= pointsToRemove From 60dce9f044cb580a46b0f60a0803888d46c9b96f Mon Sep 17 00:00:00 2001 From: ddivad195 Date: Wed, 4 Aug 2021 22:27:38 +0100 Subject: [PATCH 4/6] feat: add note about search to help menu --- src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt b/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt index f44b528..1b85719 100644 --- a/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt +++ b/src/main/kotlin/me/ddivad/judgebot/services/HelpService.kt @@ -45,7 +45,7 @@ class HelpService(private val discord: Discord) { description = """ You have **${commands.size}** commands available based on permissions. - Use `${event.prefix()}help` for more information + Use `${event.prefix()}help ` for more information """.trimIndent() color = event.discord.configuration.theme?.kColor @@ -54,6 +54,11 @@ class HelpService(private val discord: Discord) { value = "```css\n${joinNames(sorted)}\n```" inline = true } + + field { + name = "Don't see what you're looking for?" + value = "Try `search `. If the command exists in a bot, it will react with ${Emojis.whiteCheckMark}" + } } } From f1496170e8c3ffaaa4c1495faae6838f5c3fe38c Mon Sep 17 00:00:00 2001 From: David Date: Wed, 4 Aug 2021 22:31:11 +0100 Subject: [PATCH 5/6] chore: bump version --- src/main/kotlin/me/ddivad/judgebot/Main.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/ddivad/judgebot/Main.kt b/src/main/kotlin/me/ddivad/judgebot/Main.kt index 20f3987..1412f52 100644 --- a/src/main/kotlin/me/ddivad/judgebot/Main.kt +++ b/src/main/kotlin/me/ddivad/judgebot/Main.kt @@ -67,7 +67,7 @@ suspend fun main(args: Array) { field { name = "Build Info" value = "```" + - "Version: 2.3.0\n" + + "Version: 2.4.0\n" + "DiscordKt: ${versions.library}\n" + "Kotlin: $kotlinVersion" + "```" From 288ebd832368ef3f493336e170478f78f11fe759 Mon Sep 17 00:00:00 2001 From: ddivad195 Date: Wed, 4 Aug 2021 22:40:44 +0100 Subject: [PATCH 6/6] build: add github actions --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ .github/workflows/docker.yml | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ae00691 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: Build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: maven-${{ hashFiles('build.gradle') }} + restore-keys: maven- + - name: Build + run: ./gradlew build \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..2c9e1bc --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,32 @@ +name: Docker + +on: + push: + branches: [ master ] + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - + name: Checkout code + uses: actions/checkout@v2 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - + name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} + + - + name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + pull: true + push: true + tags: theprogrammershangout/judgebot:latest \ No newline at end of file