From f847d62e0015c32d81aab6be250ca2de38301eef Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Wed, 17 Jan 2024 21:01:38 +0000 Subject: [PATCH] Make checks more consistent --- .../kord/extensions/checks/MemberChecks.kt | 2 +- .../kord/extensions/checks/MiscChecks.kt | 85 +++++++++++++++++- .../kord/extensions/checks/NSFWChecks.kt | 8 +- .../kord/extensions/checks/_Events.kt | 87 ------------------- .../translations/kordex/strings.properties | 2 + .../kordex/strings_en_GB.properties | 2 + 6 files changed, 90 insertions(+), 96 deletions(-) diff --git a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MemberChecks.kt b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MemberChecks.kt index 38b1fe6e9b..b5688eb550 100644 --- a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MemberChecks.kt +++ b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MemberChecks.kt @@ -183,7 +183,7 @@ public suspend fun CheckContext<*>.notHasPermissions(perms: Permissions) { if (member == null) { logger.nullMember(event) - fail() + pass() } else { val memberObj = member.asMember() diff --git a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MiscChecks.kt b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MiscChecks.kt index 276c842211..35391ed6e6 100644 --- a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MiscChecks.kt +++ b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/MiscChecks.kt @@ -52,6 +52,44 @@ public suspend fun CheckContext<*>.isBotOwner() { } } +/** + * For bots with single owners, check asserting the user for an [Event] is not the bot's owner. + * + * Will pass if the event doesn't concern a user, or the bot doesn't have a single owner (e.g. it is part of a team). + */ +public suspend fun CheckContext<*>.isNotBotOwner() { + if (!passed) { + return + } + + val logger = KotlinLogging.logger("com.kotlindiscord.kord.extensions.checks.isNotBotOwner") + val owner = event.kord.getApplicationInfo().ownerId + + if (owner == null) { + logger.passed("Bot does not have an owner.") + + return pass() + } + + val user = userFor(event)?.asUserOrNull() + + if (user == null) { + logger.passed("Event did not concern a user.") + + pass() + } else if (user.id == owner) { + logger.failed("User owns this bot.") + + fail( + translate("checks.isNotBotOwner.failed") + ) + } else { + logger.failed("User does not own this bot.") + + pass() + } +} + /** * For bots owned by a team, check asserting the user for an [Event] is one of the bot's admins. * @@ -93,6 +131,47 @@ public suspend fun CheckContext<*>.isBotAdmin() { } } +/** + * For bots owned by a team, check asserting the user for an [Event] is not one of the bot's admins. + * + * Will pass if the event doesn't concern a user, or the bot doesn't have any admins (e.g. it has a single owner). + */ +public suspend fun CheckContext<*>.isNotBotAdmin() { + if (!passed) { + return + } + + val logger = KotlinLogging.logger("com.kotlindiscord.kord.extensions.checks.isNotBotAdmin") + val admins = event.kord.getApplicationInfo().team + ?.members + ?.filter { it.role == TeamMemberRole.Admin } + ?.map { it.userId } + + if (admins.isNullOrEmpty()) { + logger.passed("Bot does not have any admins.") + + return pass() + } + + val user = userFor(event)?.asUserOrNull() + + if (user == null) { + logger.passed("Event did not concern a user.") + + pass() + } else if (user.id in admins) { + logger.failed("User administrates this bot.") + + fail( + translate("checks.isNotBotAdmin.failed") + ) + } else { + logger.passed("User does not administrate this bot.") + + pass() + } +} + /** * Check asserting the user for an [Event] is a bot. Will fail if the event doesn't concern a user. */ @@ -122,7 +201,7 @@ public suspend fun CheckContext<*>.isBot() { } /** - * Check asserting the user for an [Event] is **not** a bot. Will fail if the event doesn't concern a user. + * Check asserting the user for an [Event] is **not** a bot. Will pass if the event doesn't concern a user. */ public suspend fun CheckContext<*>.isNotBot() { if (!passed) { @@ -133,9 +212,9 @@ public suspend fun CheckContext<*>.isNotBot() { val user = userFor(event)?.asUserOrNull() if (user == null) { - logger.failed("Event did not concern a user.") + logger.passed("Event did not concern a user.") - fail() + pass() } else if (!user.isBot) { logger.passed() diff --git a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/NSFWChecks.kt b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/NSFWChecks.kt index 59b24904fb..9737cba51d 100644 --- a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/NSFWChecks.kt +++ b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/NSFWChecks.kt @@ -74,11 +74,9 @@ public suspend fun CheckContext<*>.notHasGuildNsfwLevel(level: NsfwLevel) { val guild = guildFor(event)?.asGuildOrNull() if (guild == null) { - logger.failed("Event did not happen within a guild.") + logger.passed("Event did not happen within a guild.") - fail( - translate("checks.anyGuild.failed") - ) + pass() } else { if (guild.nsfw == level) { logger.failed("Guild matched the given NSFW level: $level") @@ -319,7 +317,7 @@ public suspend fun CheckContext<*>.notChannelIsNsfw() { if (eventChannel == null) { logger.nullChannel(event) - fail() + pass() } else if (eventChannel.type == ChannelType.DM) { logger.passed() diff --git a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/_Events.kt b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/_Events.kt index 1f9116f1e8..c630613975 100644 --- a/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/_Events.kt +++ b/kord-extensions/src/main/kotlin/com/kotlindiscord/kord/extensions/checks/_Events.kt @@ -12,7 +12,6 @@ import com.kotlindiscord.kord.extensions.events.interfaces.* import com.kotlindiscord.kord.extensions.utils.authorId import dev.kord.common.annotation.KordExperimental import dev.kord.common.annotation.KordUnsafe -import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.* import dev.kord.core.behavior.channel.ChannelBehavior import dev.kord.core.behavior.channel.threads.ThreadChannelBehavior @@ -98,92 +97,6 @@ public suspend fun topChannelFor(event: Event): ChannelBehavior? { } } -/** - * Retrieves a channel ID representing a channel that is the subject of a given event, if possible. - * - * This function only supports a specific set of events - any unsupported events will - * simply result in a `null` value. Please note that some events may support a - * null value for this type of object, and this will also be reflected in the return - * value. - * - * @param event The event concerning to the channel to retrieve. - * @return A [Long] representing the channel ID, or null if there isn't one. - */ -public suspend fun channelIdFor(event: Event): ULong? { - return when (event) { - is ChannelEvent -> event.channel?.id?.value - - is ChannelCreateEvent -> event.channel.id.value - is ChannelDeleteEvent -> event.channel.id.value - is ChannelPinsUpdateEvent -> event.channel.id.value - is ChannelUpdateEvent -> event.channel.id.value - is InteractionCreateEvent -> event.interaction.channel.id.value - is InviteCreateEvent -> event.channel.id.value - is InviteDeleteEvent -> event.channel.id.value - is MessageBulkDeleteEvent -> event.channelId.value - is MessageCreateEvent -> event.message.channel.id.value - is MessageDeleteEvent -> event.channelId.value - is MessageUpdateEvent -> event.channel.id.value - is ReactionAddEvent -> event.channel.id.value - is ReactionRemoveAllEvent -> event.channel.id.value - is ReactionRemoveEmojiEvent -> event.channel.id.value - is ReactionRemoveEvent -> event.channel.id.value - is TypingStartEvent -> event.channel.id.value - is VoiceStateUpdateEvent -> event.state.channelId?.value - is WebhookUpdateEvent -> event.channel.id.value - - is ThreadChannelDeleteEvent -> event.channel.id.value -// is ThreadListSyncEvent -> event. - is ThreadMemberUpdateEvent -> event.member.getThreadOrNull()?.id?.value -// is ThreadMembersUpdateEvent -> event. - - else -> null - } -} - -/** - * Retrieves a channel ID representing a channel that is the subject of a given event, if possible. - * - * This function only supports a specific set of events - any unsupported events will - * simply result in a `null` value. Please note that some events may support a - * null value for this type of object, and this will also be reflected in the return - * value. - * - * @param event The event concerning to the channel to retrieve. - * @return A [Snowflake] representing the channel ID, or null if there isn't one. - */ -public suspend fun channelSnowflakeFor(event: Event): Snowflake? { - return when (event) { - is ChannelEvent -> event.channel?.id - - is ChannelCreateEvent -> event.channel.id - is ChannelDeleteEvent -> event.channel.id - is ChannelPinsUpdateEvent -> event.channel.id - is ChannelUpdateEvent -> event.channel.id - is InteractionCreateEvent -> event.interaction.channel.id - is InviteCreateEvent -> event.channel.id - is InviteDeleteEvent -> event.channel.id - is MessageBulkDeleteEvent -> event.channelId - is MessageCreateEvent -> event.message.channel.id - is MessageDeleteEvent -> event.channelId - is MessageUpdateEvent -> event.channel.id - is ReactionAddEvent -> event.channel.id - is ReactionRemoveAllEvent -> event.channel.id - is ReactionRemoveEmojiEvent -> event.channel.id - is ReactionRemoveEvent -> event.channel.id - is TypingStartEvent -> event.channel.id - is VoiceStateUpdateEvent -> event.state.channelId - is WebhookUpdateEvent -> event.channel.id - - is ThreadChannelDeleteEvent -> event.channel.id -// is ThreadListSyncEvent -> event. - is ThreadMemberUpdateEvent -> event.member.getThreadOrNull()?.id -// is ThreadMembersUpdateEvent -> event. - - else -> null - } -} - /** * Retrieves a guild that is the subject of a given event, if possible. * diff --git a/kord-extensions/src/main/resources/translations/kordex/strings.properties b/kord-extensions/src/main/resources/translations/kordex/strings.properties index 49c66610a7..bff48f9397 100644 --- a/kord-extensions/src/main/resources/translations/kordex/strings.properties +++ b/kord-extensions/src/main/resources/translations/kordex/strings.properties @@ -57,6 +57,8 @@ checks.guildNsfwLevelLowerOrEqual.failed=Must be in a server with an NSFW level checks.isBot.failed=Must be a bot checks.isBotAdmin.failed=Must be one of this bot's admins checks.isBotOwner.failed=Must be this bot's owner +checks.isNotBotAdmin.failed=Must not be one of this bot's admins +checks.isNotBotOwner.failed=Must not be this bot's owner checks.isNotBot.failed=Must not be a bot checks.isInThread.failed=Must be in a thread checks.isNotInThread.failed=Must not be in a thread diff --git a/kord-extensions/src/main/resources/translations/kordex/strings_en_GB.properties b/kord-extensions/src/main/resources/translations/kordex/strings_en_GB.properties index caffd148fb..cbd01cafba 100644 --- a/kord-extensions/src/main/resources/translations/kordex/strings_en_GB.properties +++ b/kord-extensions/src/main/resources/translations/kordex/strings_en_GB.properties @@ -55,6 +55,8 @@ checks.guildNsfwLevelLowerOrEqual.failed=Must be in a server with an NSFW level checks.isBot.failed=Must be a bot checks.isBotAdmin.failed=Must be one of this bot's admins checks.isBotOwner.failed=Must be this bot's owner +checks.isNotBotAdmin.failed=Must not be one of this bot's admins +checks.isNotBotOwner.failed=Must not be this bot's owner checks.isNotBot.failed=Must not be a bot checks.isInThread.failed=Must be in a thread checks.isNotInThread.failed=Must not be in a thread