diff --git a/src/main/kotlin/org/hyacinthbots/lilybot/database/collections/LockedChannelCollection.kt b/src/main/kotlin/org/hyacinthbots/lilybot/database/collections/LockedChannelCollection.kt new file mode 100644 index 00000000..0c7150be --- /dev/null +++ b/src/main/kotlin/org/hyacinthbots/lilybot/database/collections/LockedChannelCollection.kt @@ -0,0 +1,24 @@ +package org.hyacinthbots.lilybot.database.collections + +import com.kotlindiscord.kord.extensions.koin.KordExKoinComponent +import dev.kord.common.entity.Snowflake +import org.hyacinthbots.lilybot.database.Database +import org.hyacinthbots.lilybot.database.entities.LockedChannelData +import org.koin.core.component.inject +import org.litote.kmongo.eq + +class LockedChannelCollection : KordExKoinComponent { + private val db: Database by inject() + + @PublishedApi + internal val collection = db.mainDatabase.getCollection() + + suspend inline fun addLockedChannel(data: LockedChannelData) = + collection.insertOne(data) + + suspend inline fun removeLockedChannel(inputGuildId: Snowflake, inputChannelId: Snowflake) = + collection.deleteOne(LockedChannelData::guildId eq inputGuildId, LockedChannelData::channelId eq inputChannelId) + + suspend inline fun getLockedChannel(inputGuildId: Snowflake, inputChannelId: Snowflake): LockedChannelData? = + collection.findOne(LockedChannelData::guildId eq inputGuildId, LockedChannelData::channelId eq inputChannelId) +} diff --git a/src/main/kotlin/org/hyacinthbots/lilybot/database/entities/LockedChannelData.kt b/src/main/kotlin/org/hyacinthbots/lilybot/database/entities/LockedChannelData.kt new file mode 100644 index 00000000..99393751 --- /dev/null +++ b/src/main/kotlin/org/hyacinthbots/lilybot/database/entities/LockedChannelData.kt @@ -0,0 +1,14 @@ +package org.hyacinthbots.lilybot.database.entities + +import dev.kord.common.entity.Permissions +import dev.kord.common.entity.Snowflake +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable + +@Serializable +data class LockedChannelData( + val guildId: Snowflake, + val channelId: Snowflake, + @Contextual val allowed: Permissions, + @Contextual val denied: Permissions, +) diff --git a/src/main/kotlin/org/hyacinthbots/lilybot/database/migrations/main/mainV10.kt b/src/main/kotlin/org/hyacinthbots/lilybot/database/migrations/main/mainV10.kt index b7a156b3..d363965b 100644 --- a/src/main/kotlin/org/hyacinthbots/lilybot/database/migrations/main/mainV10.kt +++ b/src/main/kotlin/org/hyacinthbots/lilybot/database/migrations/main/mainV10.kt @@ -9,4 +9,5 @@ suspend fun mainV10(db: CoroutineDatabase) { with(db.getCollection()) { updateMany(AutoThreadingData::extraRoleIds exists false, setValue(AutoThreadingData::extraRoleIds, emptyList())) } + db.createCollection("lockedChannelData") } diff --git a/src/main/kotlin/org/hyacinthbots/lilybot/extensions/moderation/LockingCommands.kt b/src/main/kotlin/org/hyacinthbots/lilybot/extensions/moderation/LockingCommands.kt index abd3c9d8..5a0d736a 100644 --- a/src/main/kotlin/org/hyacinthbots/lilybot/extensions/moderation/LockingCommands.kt +++ b/src/main/kotlin/org/hyacinthbots/lilybot/extensions/moderation/LockingCommands.kt @@ -22,6 +22,8 @@ import dev.kord.core.entity.channel.TextChannel import dev.kord.core.entity.channel.ThreadParentChannel import dev.kord.core.entity.channel.thread.TextChannelThread import kotlinx.datetime.Clock +import org.hyacinthbots.lilybot.database.collections.LockedChannelCollection +import org.hyacinthbots.lilybot.database.entities.LockedChannelData import org.hyacinthbots.lilybot.extensions.config.ConfigOptions import org.hyacinthbots.lilybot.utils.botHasChannelPerms import org.hyacinthbots.lilybot.utils.getLoggingChannelWithPerms @@ -49,15 +51,9 @@ class LockingCommands : Extension() { check { anyGuild() - requiredConfigs( - ConfigOptions.MODERATION_ENABLED - ) + requiredConfigs(ConfigOptions.MODERATION_ENABLED) hasPermission(Permission.ModerateMembers) - requireBotPermissions( - Permission.ManageChannels, - Permission.ManageRoles, - Permission.SendMessages - ) + requireBotPermissions(Permission.ManageChannels, Permission.ManageRoles) botHasChannelPerms(Permissions(Permission.ManageChannels)) } @@ -66,12 +62,28 @@ class LockingCommands : Extension() { val channelParent = getChannelParent(channelArg) val targetChannel = getTargetChannel(channelParent, channelArg) - val channelPerms = targetChannel!!.getPermissionOverwritesForRole(guild!!.id) - if (channelPerms != null && channelPerms.denied.contains(Permission.SendMessages)) { - respond { content = "This channel is already locked!" } + val currentChannelPerms = targetChannel?.getPermissionOverwritesForRole(guild!!.id) + if (currentChannelPerms == null) { + respond { + content = "There was an error getting the permissions for this channel. Please try again." + } return@action } + if (LockedChannelCollection().getLockedChannel(guild!!.id, targetChannel.id) != null) { + respond { content = "This channel is already locked" } + return@action + } + + LockedChannelCollection().addLockedChannel( + LockedChannelData( + guildId = guild!!.id, + channelId = targetChannel.id, + allowed = currentChannelPerms.data.allowed, + denied = currentChannelPerms.data.denied + ) + ) + val everyoneRole = guild!!.getRoleOrNull(guild!!.id) if (everyoneRole == null) { respond { content = "I was unable to get the `@everyone` role. Please try again." } @@ -119,15 +131,9 @@ class LockingCommands : Extension() { check { anyGuild() - requiredConfigs( - ConfigOptions.MODERATION_ENABLED - ) + requiredConfigs(ConfigOptions.MODERATION_ENABLED) hasPermission(Permission.ModerateMembers) - requireBotPermissions( - Permission.ManageChannels, - Permission.ManageRoles, - Permission.SendMessages - ) + requireBotPermissions(Permission.ManageChannels, Permission.ManageRoles, Permission.SendMessages) } action { @@ -187,11 +193,7 @@ class LockingCommands : Extension() { anyGuild() requiredConfigs(ConfigOptions.MODERATION_ENABLED) hasPermission(Permission.ModerateMembers) - requireBotPermissions( - Permission.ManageChannels, - Permission.ManageRoles, - Permission.SendMessages - ) + requireBotPermissions(Permission.ManageChannels, Permission.ManageRoles) botHasChannelPerms(Permissions(Permission.ManageChannels)) } @@ -209,30 +211,31 @@ class LockingCommands : Extension() { return@action } - val channelPerms = targetChannel!!.getPermissionOverwritesForRole(guild!!.id) + val channelPerms = targetChannel?.getPermissionOverwritesForRole(guild!!.id) if (channelPerms == null) { respond { content = "This channel is not locked!" } return@action } - if (!channelPerms.denied.contains(Permission.SendMessages)) { + val lockedChannel = LockedChannelCollection().getLockedChannel(guild!!.id, targetChannel.id) + if (lockedChannel == null) { respond { content = "This channel is not locked!" } return@action } targetChannel.editRolePermission(guild!!.id) { - denied -= Permission.SendMessages - denied -= Permission.SendMessagesInThreads - denied -= Permission.AddReactions - denied -= Permission.UseApplicationCommands + denied = lockedChannel.denied + allowed = lockedChannel.allowed } targetChannel.createEmbed { title = "Channel Unlocked" description = "This channel has been unlocked by a moderator.\n" + - "Please be aware of the rules when continuing discussion." + "Please be aware of the rules when continuing discussion." color = DISCORD_GREEN } + LockedChannelCollection().removeLockedChannel(guild!!.id, targetChannel.id) + respond { content = "${targetChannel.mention} has been unlocked." } val actionLog = @@ -258,15 +261,9 @@ class LockingCommands : Extension() { check { anyGuild() - requiredConfigs( - ConfigOptions.MODERATION_ENABLED - ) + requiredConfigs(ConfigOptions.MODERATION_ENABLED) hasPermission(Permission.ModerateMembers) - requireBotPermissions( - Permission.ManageChannels, - Permission.ManageRoles, - Permission.SendMessages - ) + requireBotPermissions(Permission.ManageChannels, Permission.ManageRoles, Permission.SendMessages) } action { @@ -334,9 +331,9 @@ class LockingCommands : Extension() { * @since 4.8.0 */ private suspend inline fun EphemeralInteractionContext.getTargetChannel( - channelParent: TextChannel?, - channelArg: Channel? - ): TextChannel? { + channelParent: TextChannel?, + channelArg: Channel? + ): TextChannel? { val targetChannel = channelParent ?: channelArg?.asChannelOfOrNull() if (targetChannel == null) { respond {