From fb499c3d05deea053a95d08885927686dedccaa9 Mon Sep 17 00:00:00 2001 From: Tomachi <8929706+book000@users.noreply.github.com> Date: Sun, 7 Jul 2024 22:09:06 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BB=E9=8C=B2=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89=20"vcspeaker=20remove"=20?= =?UTF-8?q?=E3=81=AE=E8=BF=BD=E5=8A=A0=20(#173)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 登録削除コマンド "vcspeaker remove" の追加 * docs: ドキュメントの更新 * feat: 削除前の確認処理と、エイリアスなどの設定削除を追加 * Apply suggestions from code review Co-authored-by: yuuaHP --------- Co-authored-by: yuuaHP --- docs/for-users/commands/vcspeaker.md | 18 ++- .../vcspeaker/commands/VCSpeakerCommand.kt | 109 ++++++++++++++++++ .../com/jaoafa/vcspeaker/stores/AliasStore.kt | 5 + .../jaoafa/vcspeaker/stores/IgnoreStore.kt | 5 + .../com/jaoafa/vcspeaker/stores/TitleStore.kt | 6 +- 5 files changed, 141 insertions(+), 2 deletions(-) diff --git a/docs/for-users/commands/vcspeaker.md b/docs/for-users/commands/vcspeaker.md index 86339148..7e069304 100644 --- a/docs/for-users/commands/vcspeaker.md +++ b/docs/for-users/commands/vcspeaker.md @@ -15,7 +15,8 @@ VCSpeaker を再起動します。 ### settings -VCSpeaker の設定を行います。この設定は、サーバごとに保存されます。 +VCSpeaker の設定を行います。この設定は、サーバごとに保存されます。 +VCSpeaker を使いはじめる場合、この設定操作を行うことによって登録されます。 ```text /vcspeaker settings [channel] [prefix] [speaker] [emotion] [emotion-level] [pitch] [speed] [volume] [auto-join] @@ -31,6 +32,21 @@ VCSpeaker の設定を行います。この設定は、サーバごとに保存 - `[volume]`: 音量 (50% から 200%) - `[auto-join]`: ボイスチャンネルに自動で入退室するかどうか +### remove + +VCSpeaker の登録を削除します。 +コマンド実行後、「はい」を選択することで削除されます。 + +```text +/vcspeaker remove +``` + +登録を削除すると、サーバに関連する以下の情報も削除されます。 + +- エイリアス +- 無視ルール +- タイトル + ## 注意事項 - `restart` サブコマンドを使用すると、Bot は即座に再起動されます。これにより、一時的に Bot が使用不可能になることがあります。 diff --git a/src/main/kotlin/com/jaoafa/vcspeaker/commands/VCSpeakerCommand.kt b/src/main/kotlin/com/jaoafa/vcspeaker/commands/VCSpeakerCommand.kt index b89fda8f..7e125f94 100644 --- a/src/main/kotlin/com/jaoafa/vcspeaker/commands/VCSpeakerCommand.kt +++ b/src/main/kotlin/com/jaoafa/vcspeaker/commands/VCSpeakerCommand.kt @@ -1,11 +1,17 @@ package com.jaoafa.vcspeaker.commands +import com.jaoafa.vcspeaker.stores.AliasStore import com.jaoafa.vcspeaker.stores.GuildStore +import com.jaoafa.vcspeaker.stores.IgnoreStore +import com.jaoafa.vcspeaker.stores.TitleStore import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.asChannelOf import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.authorOf +import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.errorColor +import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.infoColor import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.respond import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.respondEmbed import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.successColor +import com.jaoafa.vcspeaker.tools.discord.DiscordExtensions.warningColor import com.jaoafa.vcspeaker.tools.discord.DiscordLoggingExtension.log import com.jaoafa.vcspeaker.tools.discord.Options import com.jaoafa.vcspeaker.tools.discord.SlashCommandExtensions.publicSlashCommand @@ -19,9 +25,13 @@ import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalBoolea import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalChannel import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalInt import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalString +import com.kotlindiscord.kord.extensions.components.components +import com.kotlindiscord.kord.extensions.components.publicButton import com.kotlindiscord.kord.extensions.extensions.Extension +import dev.kord.common.entity.ButtonStyle import dev.kord.common.entity.ChannelType import dev.kord.core.entity.channel.TextChannel +import dev.kord.rest.builder.message.embed import io.github.oshai.kotlinlogging.KotlinLogging import kotlin.system.exitProcess @@ -211,6 +221,105 @@ class VCSpeakerCommand : Extension() { } } } + + publicSubCommand("remove", "VCSpeaker の登録を削除します。") { + action { + val guildId = guild!!.id + val guildData = GuildStore[guildId] + + if (guildData == null) { + respond("**:x: このサーバーは登録されていません。**") + return@action + } + + val confirmUser = user + + // 削除する前に確認を設ける + respond { + embed { + title = ":wastebasket: Confirm registration removal" + description = "VCSpeaker の登録を削除しますが、よろしいですか?" + authorOf(user) + warningColor() + } + + components { + publicButton { + label = "はい" + style = ButtonStyle.Primary + deferredAck = true + action buttonAction@{ + // 異なるユーザーが操作できないようにする + if (user.id != confirmUser.id) { + respondEmbed( + ":x: Failed to remove registration", + "この操作は実行者のみが実行できます。" + ) { + authorOf(user) + + errorColor() + } + + return@buttonAction + } + + // 各種データを削除 + AliasStore.removeForGuild(guildId) + IgnoreStore.removeForGuild(guildId) + TitleStore.removeForGuild(guildId) + GuildStore.remove(guildData) + edit { + embed { + title = ":wastebasket: Registration removed" + description = "VCSpeaker の登録を削除しました。" + + authorOf(user) + successColor() + } + + components {} + } + + log(logger) { guild, user -> + "[${guild.name}] Registration Removed: Removed by @${user.username}" + } + } + } + + publicButton { + label = "いいえ" + style = ButtonStyle.Danger + action buttonAction@{ + if (user.id != confirmUser.id) { + respondEmbed( + ":x: Failed to remove registration", + "この操作は実行者のみが実行できます。" + ) { + authorOf(user) + + errorColor() + } + + return@buttonAction + } + + edit { + embed { + title = ":wastebasket: Registration removal canceled" + description = "VCSpeaker の登録削除をキャンセルしました。" + + authorOf(user) + infoColor() + } + + components {} + } + } + } + } + } + } + } } } } \ No newline at end of file diff --git a/src/main/kotlin/com/jaoafa/vcspeaker/stores/AliasStore.kt b/src/main/kotlin/com/jaoafa/vcspeaker/stores/AliasStore.kt index 45f25956..85738ab7 100644 --- a/src/main/kotlin/com/jaoafa/vcspeaker/stores/AliasStore.kt +++ b/src/main/kotlin/com/jaoafa/vcspeaker/stores/AliasStore.kt @@ -38,5 +38,10 @@ object AliasStore : StoreStruct( data.find { it.guildId == guildId && it.search == from } fun filter(guildId: Snowflake?) = data.filter { it.guildId == guildId } + + fun removeForGuild(guildId: Snowflake) { + data.removeIf { it.guildId == guildId } + write() + } } diff --git a/src/main/kotlin/com/jaoafa/vcspeaker/stores/IgnoreStore.kt b/src/main/kotlin/com/jaoafa/vcspeaker/stores/IgnoreStore.kt index 20ddcfe7..9a913900 100644 --- a/src/main/kotlin/com/jaoafa/vcspeaker/stores/IgnoreStore.kt +++ b/src/main/kotlin/com/jaoafa/vcspeaker/stores/IgnoreStore.kt @@ -34,4 +34,9 @@ object IgnoreStore : StoreStruct( fun find(guildId: Snowflake, text: String) = data.find { it.guildId == guildId && it.search == text } fun filter(guildId: Snowflake?) = data.filter { it.guildId == guildId } + + fun removeForGuild(guildId: Snowflake) { + data.removeIf { it.guildId == guildId } + write() + } } \ No newline at end of file diff --git a/src/main/kotlin/com/jaoafa/vcspeaker/stores/TitleStore.kt b/src/main/kotlin/com/jaoafa/vcspeaker/stores/TitleStore.kt index 50d7dad1..731000ea 100644 --- a/src/main/kotlin/com/jaoafa/vcspeaker/stores/TitleStore.kt +++ b/src/main/kotlin/com/jaoafa/vcspeaker/stores/TitleStore.kt @@ -3,7 +3,6 @@ package com.jaoafa.vcspeaker.stores import com.jaoafa.vcspeaker.VCSpeaker import dev.kord.common.entity.Snowflake import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json @Serializable @@ -23,4 +22,9 @@ object TitleStore : StoreStruct( fun find(channelId: Snowflake) = data.find { it.channelId == channelId } fun filterGuild(guildId: Snowflake) = data.filter { it.guildId == guildId } + + fun removeForGuild(guildId: Snowflake) { + data.removeIf { it.guildId == guildId } + write() + } } \ No newline at end of file