From 1347155817fe173138bffa710066cebff0acdb00 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 20 Jun 2025 23:42:16 +0200 Subject: [PATCH 01/21] Add BuiltinReplies[Factory] --- .../handler/DefaultRateLimitHandler.kt | 44 +++--- .../api/core/replies/BuiltinReplies.kt | 107 +++++++++++++++ .../api/core/replies/BuiltinRepliesFactory.kt | 38 ++++++ .../api/core/replies/DefaultBuiltinReplies.kt | 128 ++++++++++++++++++ .../replies/DefaultBuiltinRepliesFactory.kt | 63 +++++++++ .../service/annotations/InterfacedService.kt | 4 +- .../application/ApplicationCommandListener.kt | 51 ++++--- .../application/slash/SlashCommandInfoImpl.kt | 12 +- .../ratelimit/handler/RateLimitHandler.kt | 8 +- .../internal/commands/text/HelpCommand.kt | 10 +- .../commands/text/TextCommandsListener.kt | 46 ++++--- .../controller/ComponentsListener.kt | 15 +- .../handler/ComponentHandlerExecutor.kt | 7 +- .../internal/modals/ModalListener.kt | 11 +- .../AbstractUserSnowflakeResolver.kt | 9 +- .../resolvers/ChannelResolverFactory.kt | 16 +-- .../botcommands/internal/utils/Exceptions.kt | 3 +- 17 files changed, 463 insertions(+), 109 deletions(-) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt index 69ba9ff6a..9930a0473 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt @@ -7,22 +7,26 @@ import io.github.freya022.botcommands.api.commands.application.ApplicationComman import io.github.freya022.botcommands.api.commands.ratelimit.RateLimitScope import io.github.freya022.botcommands.api.commands.text.TextCommandInfo import io.github.freya022.botcommands.api.core.BContext +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.awaitCatching import io.github.freya022.botcommands.api.core.utils.namedDefaultScope import io.github.freya022.botcommands.api.core.utils.runIgnoringResponse import io.github.freya022.botcommands.api.localization.DefaultMessages -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel +import net.dv8tion.jda.api.events.Event +import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.interactions.callbacks.IMessageEditCallback import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback import net.dv8tion.jda.api.requests.ErrorResponse -import net.dv8tion.jda.api.utils.TimeFormat +import net.dv8tion.jda.api.utils.messages.MessageCreateData +import java.time.Instant import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.nanoseconds @@ -59,8 +63,8 @@ class DefaultRateLimitHandler( event.guildChannel.canTalk() -> event.channel else -> event.author.openPrivateChannel().await() } - val messages = context.getService().get(event) - val content = getRateLimitMessage(messages, probe) + val messages = context.getService().get(event) + val content = getRateLimitMessage(event, messages, probe) runIgnoringResponse(ErrorResponse.CANNOT_SEND_TO_USER) { val messageId = channel.sendMessage(content).await().idLong @@ -80,7 +84,7 @@ class DefaultRateLimitHandler( commandInfo: ApplicationCommandInfo, probe: ConsumptionProbe ) where T : GenericCommandInteractionEvent, T : IReplyCallback { - onRateLimit(context, event, probe) + onRateLimit0(context, event, probe) } override suspend fun onRateLimit( @@ -88,12 +92,17 @@ class DefaultRateLimitHandler( event: T, probe: ConsumptionProbe ) where T : GenericComponentInteractionCreateEvent, T : IReplyCallback, T : IMessageEditCallback { - onRateLimit(context, event as IReplyCallback, probe) + onRateLimit0(context, event, probe) } - private suspend fun onRateLimit(context: BContext, event: IReplyCallback, probe: ConsumptionProbe) { - val messages = context.getService().get(event) - val content = getRateLimitMessage(messages, probe) + private suspend fun onRateLimit0( + context: BContext, + event: T, + probe: ConsumptionProbe + ) where T : GenericInteractionCreateEvent, + T : IReplyCallback { + val messages = context.getService().get(event) + val content = getRateLimitMessage(event, messages, probe) val hook = event.reply(content).setEphemeral(true).await() // Only schedule delete if the interaction hook doesn't expire before // Technically this is supposed to be 15 minutes but, just to be safe @@ -106,16 +115,17 @@ class DefaultRateLimitHandler( } private fun getRateLimitMessage( - messages: DefaultMessages, + event: Event, + replies: BuiltinReplies, probe: ConsumptionProbe - ): String { - val timestamp = TimeFormat.RELATIVE.atTimestamp(System.currentTimeMillis() + probe.nanosToWaitForRefill.floorDiv(1_000_000)) + ): MessageCreateData { + val deadline = Instant.now().plusNanos(probe.nanosToWaitForRefill) return when (scope) { - RateLimitScope.USER -> messages.getUserRateLimitMsg(timestamp) - RateLimitScope.USER_PER_GUILD -> messages.getUserRateLimitMsg(timestamp) - RateLimitScope.USER_PER_CHANNEL -> messages.getUserRateLimitMsg(timestamp) - RateLimitScope.GUILD -> messages.getGuildRateLimitMsg(timestamp) - RateLimitScope.CHANNEL -> messages.getChannelRateLimitMsg(timestamp) + RateLimitScope.USER -> replies.userRateLimited(event, deadline) + RateLimitScope.USER_PER_GUILD -> replies.userRateLimited(event, deadline) + RateLimitScope.USER_PER_CHANNEL -> replies.userRateLimited(event, deadline) + RateLimitScope.GUILD -> replies.guildRateLimited(event, deadline) + RateLimitScope.CHANNEL -> replies.channelRateLimited(event, deadline) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt new file mode 100644 index 000000000..6a1abd0d5 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt @@ -0,0 +1,107 @@ +package io.github.freya022.botcommands.api.core.replies + +import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption +import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo +import net.dv8tion.jda.api.Permission +import net.dv8tion.jda.api.entities.channel.attribute.IAgeRestrictedChannel +import net.dv8tion.jda.api.events.GenericEvent +import net.dv8tion.jda.api.utils.messages.MessageCreateData +import java.time.Instant + +/** + * Returns the messages used by the framework, instance produced by [BuiltinRepliesFactory]. + * + * @see BuiltinRepliesFactory + */ +interface BuiltinReplies { + + /** + * @return Message to display when an uncaught exception occurs + */ + fun uncaughtException(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when the user does not have enough permissions + */ + fun missingUserPermissions(event: GenericEvent?, permissions: Set): MessageCreateData + + /** + * @return Message to display when the bot does not have enough permissions + */ + fun missingBotPermissions(event: GenericEvent?, permissions: Set): MessageCreateData + + /** + * @return Message to display when the command is only usable by the owner + */ + fun ownerOnly(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when the command is on per-user rate limit + */ + fun userRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData + + /** + * @return Message to display when the command is on per-channel rate limit + */ + fun channelRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData + + /** + * @return Message to display when the command is on per-guild rate limit + */ + fun guildRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData + + /** + * @return Message to display when application commands are not loaded on the guild yet + */ + fun applicationCommandsNotAvailable(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when the command is not found + */ + fun commandNotFound(event: GenericEvent?, suggestions: Collection): MessageCreateData + + /** + * @return Message to display when a channel parameter could not be resolved + */ + fun resolverChannelNotFound(event: GenericEvent?, channelId: Long): MessageCreateData + + /** + * @return Message to display when a channel parameter could not be resolved + */ + fun resolverChannelMissingAccess(event: GenericEvent?, channelId: Long): MessageCreateData + + /** + * @return Message to display when a user parameter could not be resolved + */ + fun resolverUserNotFound(event: GenericEvent?, userId: Long): MessageCreateData + + /** + * @return Message to display when a slash command option is unresolvable (only in slash command interactions) + */ + fun slashCommandUnresolvableOption(event: GenericEvent?, option: SlashCommandOption): MessageCreateData + + /** + * @return Message to display when a User's DMs are closed (when sending help content for example) + */ + fun closedDirectMessages(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when a command is used in a NSFW [IAgeRestrictedChannel] + */ + fun nsfwOnly(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when a user tries to use a component it cannot interact with + */ + fun componentNotAllowed(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when a user tries to use a component which has reached timeout while the bot was offline + */ + fun componentExpired(event: GenericEvent?): MessageCreateData + + /** + * @return Message to display when a user tries to use a modal which has reached timeout + */ + fun modalExpired(event: GenericEvent?): MessageCreateData +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt new file mode 100644 index 000000000..cd9f279d0 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt @@ -0,0 +1,38 @@ +package io.github.freya022.botcommands.api.core.replies + +import io.github.freya022.botcommands.api.core.service.annotations.BService +import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider +import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import java.util.* + +/** + * Factory of [BuiltinReplies], the default implementation is [DefaultBuiltinRepliesFactory], or, + * if a non-default [DefaultMessagesFactory] exists, an adapter is used. + * + * **Usage**: Register your instance as a service with [@BService][BService]. + */ +@InterfacedService(acceptMultiple = false) +interface BuiltinRepliesFactory { + /** + * Retrieves a [BuiltinReplies] instance for the given locale. + */ + fun get(locale: Locale): BuiltinReplies + + /** + * Retrieves a [BuiltinReplies] instance, with the locale derived from this event. + * + * By default, this uses [TextCommandLocaleProvider] to get the locale. + */ + fun get(event: MessageReceivedEvent): BuiltinReplies + + /** + * Retrieves a [BuiltinReplies] instance, with the locale derived from this interaction. + * + * By default, this uses [UserLocaleProvider] to get the locale. + */ + fun get(event: Interaction): BuiltinReplies +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt new file mode 100644 index 000000000..967dc762d --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt @@ -0,0 +1,128 @@ +package io.github.freya022.botcommands.api.core.replies + +import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption +import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo +import io.github.freya022.botcommands.api.localization.Localization +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.LocalizationTemplate +import io.github.freya022.botcommands.api.localization.localize +import io.github.freya022.botcommands.internal.utils.throwArgument +import net.dv8tion.jda.api.Permission +import net.dv8tion.jda.api.events.GenericEvent +import net.dv8tion.jda.api.utils.TimeFormat +import net.dv8tion.jda.api.utils.messages.MessageCreateData +import java.time.Instant +import java.util.* + +/** + * Default implementation of [BuiltinReplies], + * see [DefaultBuiltinRepliesFactory] for more details. + * + * @see DefaultBuiltinRepliesFactory + */ +open class DefaultBuiltinReplies( + localizationService: LocalizationService, + locale: Locale, + bundleName: String, +) : BuiltinReplies { + + protected val localization: Localization = localizationService.getInstance(bundleName, locale) ?: run { + val mappingProviders = localizationService.getMappingProviders() + val mappingReaders = localizationService.getMappingReaders() + throwArgument("Could find localization files for '$bundleName', providers: $mappingProviders, readers: $mappingReaders") + } + + protected val permissionsLocalization: Localization? = localizationService.getInstance("Permissions", locale) + + override fun uncaughtException(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("uncaught_exception").localize().toMessage() + } + + override fun missingUserPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { + val localizedPermissions = permissions.joinToString(separator = ", ", transform = ::getLocalizedPermission) + return getLocalizationTemplate("missing.permissions.user").localize("permissions" to localizedPermissions).toMessage() + } + + override fun missingBotPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { + val localizedPermissions = permissions.joinToString(separator = ", ", transform = ::getLocalizedPermission) + return getLocalizationTemplate("missing.permissions.bot").localize("permissions" to localizedPermissions).toMessage() + } + + override fun ownerOnly(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("owner_only").localize().toMessage() + } + + override fun userRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + val args = "timestamp" to TimeFormat.RELATIVE.atInstant(deadline) + return getLocalizationTemplate("ratelimited.user").localize(args).toMessage() + } + + override fun channelRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + val timestamp = TimeFormat.RELATIVE.atInstant(deadline) + return getLocalizationTemplate("ratelimited.channel").localize("timestamp" to timestamp).toMessage() + } + + override fun guildRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + val timestamp = TimeFormat.RELATIVE.atInstant(deadline) + return getLocalizationTemplate("ratelimited.guild").localize("timestamp" to timestamp).toMessage() + } + + override fun applicationCommandsNotAvailable(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("commands.application.not_available").localize().toMessage() + } + + override fun commandNotFound(event: GenericEvent?, suggestions: Collection): MessageCreateData { + val suggestionsStr = suggestions.joinToString(separator = "**, **", prefix = "**", postfix = "**") { it.name } + return getLocalizationTemplate("commands.text.not_found").localize("suggestions" to suggestionsStr).toMessage() + } + + override fun resolverChannelNotFound(event: GenericEvent?, channelId: Long): MessageCreateData { + return getLocalizationTemplate("resolver.channel.not_found").localize("channelId" to channelId).toMessage() + } + + override fun resolverChannelMissingAccess(event: GenericEvent?, channelId: Long): MessageCreateData { + return getLocalizationTemplate("resolver.channel.missing_access").localize("channelId" to channelId).toMessage() + } + + override fun resolverUserNotFound(event: GenericEvent?, userId: Long): MessageCreateData { + return getLocalizationTemplate("resolver.user.not_found").localize("userId" to userId).toMessage() + } + + override fun slashCommandUnresolvableOption(event: GenericEvent?, option: SlashCommandOption): MessageCreateData { + return getLocalizationTemplate("commands.slash.option.unresolvable").localize("optionName" to option.discordName).toMessage() + } + + override fun closedDirectMessages(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("direct_messages.closed").localize().toMessage() + } + + override fun nsfwOnly(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("nsfw_only").localize().toMessage() + } + + override fun componentNotAllowed(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("components.not_allowed").localize().toMessage() + } + + override fun componentExpired(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("components.expired").localize().toMessage() + } + + override fun modalExpired(event: GenericEvent?): MessageCreateData { + return getLocalizationTemplate("modals.expired").localize().toMessage() + } + + protected fun getLocalizationTemplate(path: String): LocalizationTemplate { + val template = localization[path] + ?: throwArgument("Template '$path' could not be found, available keys: ${localization.keys}") + + return template + } + + protected fun getLocalizedPermission(permission: Permission): String { + @Suppress("UsePropertyAccessSyntax") // `permission.name` targets Enum#name() which is definitely not the same + return permissionsLocalization?.get(permission.name)?.localize() ?: permission.getName() + } + + protected fun String.toMessage(): MessageCreateData = MessageCreateData.fromContent(this) +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt new file mode 100644 index 000000000..99c023987 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt @@ -0,0 +1,63 @@ +package io.github.freya022.botcommands.api.core.replies + +import io.github.freya022.botcommands.api.localization.Localization +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider +import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import java.util.* +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +/** + * Default implementation of [BuiltinRepliesFactory]. + * + * Instances returned by this factory are [DefaultBuiltinReplies], + * which uses [LocalizationService] to get a localization bundle using the provided [bundleName]. + * + * By default, an instance of this factory is registered using the default bundle name (`BuiltinReplies`), + * you can override the default factory by providing a corresponding service factory. + * + * ### Light customization / Supporting more locales + * + * With the default values, the localization templates would be loaded from `/bc_localization/BuiltinReplies-default.json`, + * you may change the values by creating a new `BuiltinReplies.json`, + * you can also support more locales following by appending an underscore and the [language tag][Locale.toLanguageTag], + * such as `BuiltinReplies_fr.json`. + * + * The localization paths must be identical to those used by [DefaultBuiltinReplies], + * but the placeholders can be modified but must keep the same names, they can also be removed. + * + * Refer to [Localization] for mode customization details. + * + * ### Complete customization + * + * Returning a [BuiltinRepliesFactory] from a service factory will disable the default implementation, + * this will let you return a completely custom instance, + * in which you can craft entirely custom messages in any way you see fit. + * + * @see Localization + */ +class DefaultBuiltinRepliesFactory( + private val localizationService: LocalizationService, + private val textCommandLocaleProvider: TextCommandLocaleProvider, + private val userLocaleProvider: UserLocaleProvider, + private val bundleName: String = "BuiltinReplies", +) : BuiltinRepliesFactory { + + private val cache: MutableMap = hashMapOf() + private val lock = ReentrantLock() + + override fun get(locale: Locale): BuiltinReplies { + cache[locale]?.let { return it } + + return lock.withLock { + cache.getOrPut(locale) { DefaultBuiltinReplies(localizationService, locale, bundleName) } + } + } + + override fun get(event: MessageReceivedEvent): BuiltinReplies = get(textCommandLocaleProvider.getLocale(event)) + + override fun get(event: Interaction): BuiltinReplies = get(userLocaleProvider.getLocale(event)) +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt index 253377a60..6c2e3897f 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt @@ -14,8 +14,8 @@ import io.github.freya022.botcommands.api.components.ComponentInteractionFilter import io.github.freya022.botcommands.api.core.* import io.github.freya022.botcommands.api.core.db.ConnectionSupplier import io.github.freya022.botcommands.api.core.db.query.ParametrizedQueryFactory +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.ServiceContainer -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.arguments.factories.FormattableArgumentFactory import io.github.freya022.botcommands.api.localization.providers.LocalizationMapProvider import io.github.freya022.botcommands.api.localization.readers.LocalizationMapReader @@ -37,7 +37,7 @@ import io.github.freya022.botcommands.api.localization.readers.LocalizationMapRe * @see ICoroutineEventManagerSupplier * @see JDAService * - * @see DefaultMessagesFactory + * @see BuiltinRepliesFactory * * @see GlobalExceptionHandler * diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt index a3ae3f41a..7ff227577 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt @@ -1,6 +1,5 @@ package io.github.freya022.botcommands.internal.commands.application -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.commands.Usability.UnusableReason import io.github.freya022.botcommands.api.commands.application.ApplicationCommandFilter import io.github.freya022.botcommands.api.commands.application.annotations.RequiresApplicationCommands @@ -16,10 +15,11 @@ import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.entities.inputUser +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.getMissingPermissions -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.commands.application.cache.factory.ApplicationCommandsCacheFactory import io.github.freya022.botcommands.internal.commands.application.context.message.MessageCommandInfoImpl import io.github.freya022.botcommands.internal.commands.application.context.user.UserCommandInfoImpl @@ -40,6 +40,8 @@ import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionE import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent import net.dv8tion.jda.api.exceptions.InsufficientPermissionException +import net.dv8tion.jda.api.interactions.Interaction +import net.dv8tion.jda.api.utils.messages.MessageCreateData private val logger = KotlinLogging.logger { } @@ -48,7 +50,7 @@ private val logger = KotlinLogging.logger { } internal class ApplicationCommandListener internal constructor( private val context: BContext, private val applicationCommandsBuilder: ApplicationCommandsBuilder, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val rateLimitHandler: RateLimitHandler, filters: List, @@ -144,7 +146,7 @@ internal class ApplicationCommandListener internal constructor( } else { logger.debug { "Ignored '${event.fullCommandName}' as guild (${guild!!.id}) commands could not be updated" } } - return event.reply_(defaultMessagesFactory.get(event).applicationCommandsNotAvailableMsg, ephemeral = true).queue() + return event.reply(builtinRepliesFactory.get(event).applicationCommandsNotAvailable(event)).setEphemeral(true).queue() } //This is done so warnings are printed after the exception @@ -225,29 +227,31 @@ internal class ApplicationCommandListener internal constructor( exceptionHandler.handleException(event, e, "application command '${event.commandString}'", emptyMap(), logLevel) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(defaultMessagesFactory.get(event).getBotPermErrorMsg(setOf(e.permission))) + event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(defaultMessagesFactory.get(event).generalErrorMsg) + event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) } } private suspend fun canRun(event: GenericCommandInteractionEvent, applicationCommand: ApplicationCommandInfoImpl): Boolean { val usability = applicationCommand.getUsability(event.inputUser, event.messageChannel) if (usability.isNotUsable) { - val errorMessage: String = when (usability.bestReason) { - UnusableReason.OWNER_ONLY -> defaultMessagesFactory.get(event).ownerOnlyErrorMsg - UnusableReason.USER_PERMISSIONS -> { - val member = event.member ?: throwInternal("USER_PERMISSIONS got checked even if guild is null") - val missingPermissions = getMissingPermissions(applicationCommand.userPermissions, member, event.guildChannel) - defaultMessagesFactory.get(event).getUserPermErrorMsg(missingPermissions) - } - UnusableReason.BOT_PERMISSIONS -> { - val guild = event.guild ?: throwInternal("BOT_PERMISSIONS got checked even if guild is null") - val missingPermissions = getMissingPermissions(applicationCommand.botPermissions, guild.selfMember, event.guildChannel) - defaultMessagesFactory.get(event).getBotPermErrorMsg(missingPermissions) + val errorMessage = fromReplies(event) { + when (usability.bestReason) { + UnusableReason.OWNER_ONLY -> ownerOnly(event) + UnusableReason.USER_PERMISSIONS -> { + val member = event.member ?: throwInternal("USER_PERMISSIONS got checked even if guild is null") + val missingPermissions = getMissingPermissions(applicationCommand.userPermissions, member, event.guildChannel) + missingUserPermissions(event, missingPermissions) + } + UnusableReason.BOT_PERMISSIONS -> { + val guild = event.guild ?: throwInternal("BOT_PERMISSIONS got checked even if guild is null") + val missingPermissions = getMissingPermissions(applicationCommand.botPermissions, guild.selfMember, event.guildChannel) + missingBotPermissions(event, missingPermissions) + } + UnusableReason.NSFW_ONLY -> throwInternal("Discord already handles NSFW commands") + UnusableReason.HIDDEN -> throwInternal("Application commands can't be hidden") } - UnusableReason.NSFW_ONLY -> throwInternal("Discord already handles NSFW commands") - UnusableReason.HIDDEN -> throwInternal("Application commands can't be hidden") } reply(event, errorMessage) return false @@ -268,10 +272,15 @@ internal class ApplicationCommandListener internal constructor( return true } - private fun reply(event: GenericCommandInteractionEvent, msg: String) { - event.reply_(msg, ephemeral = true) + private fun reply(event: GenericCommandInteractionEvent, message: MessageCreateData) { + event.reply(message) + .setEphemeral(true) .queue(null) { throwable -> exceptionHandler.handleException(event, throwable, "interaction reply", emptyMap()) } } + + private inline fun fromReplies(event: Interaction, crossinline block: BuiltinReplies.() -> MessageCreateData): MessageCreateData { + return builtinRepliesFactory.get(event).run(block) + } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt index 6e82e6bc0..815c4c15a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt @@ -1,14 +1,13 @@ package io.github.freya022.botcommands.internal.commands.application.slash -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.commands.INamedCommand import io.github.freya022.botcommands.api.commands.application.slash.GlobalSlashEvent import io.github.freya022.botcommands.api.commands.application.slash.GuildSlashEvent import io.github.freya022.botcommands.api.commands.application.slash.SlashCommandInfo import io.github.freya022.botcommands.api.core.BContext +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.simpleNestedName -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.* import io.github.freya022.botcommands.internal.commands.application.ApplicationCommandInfoImpl import io.github.freya022.botcommands.internal.commands.application.options.ApplicationGeneratedOption @@ -156,11 +155,10 @@ private fun onUnresolvableOption( else -> { //Only use the generic message if the user didn't handle this situation if (!event.isAcknowledged && event is SlashCommandInteractionEvent) { - val defaultMessages = option.context.getService().get(event) - event.reply_( - defaultMessages.getSlashCommandUnresolvableOptionMsg(option.discordName), - ephemeral = true - ).queue() + val defaultMessages = option.context.getService().get(event) + event.reply(defaultMessages.slashCommandUnresolvableOption(event, option)) + .setEphemeral(true) + .queue() } InsertOptionResult.ABORT diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt index ab3f2d105..d1b47fa57 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt @@ -1,14 +1,13 @@ package io.github.freya022.botcommands.internal.commands.ratelimit.handler -import dev.minn.jda.ktx.messages.reply_ import io.github.bucket4j.Bucket import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimit import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.BotOwners import io.github.freya022.botcommands.api.core.config.BConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.loggerOf -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.commands.application.ApplicationCommandInfoImpl import io.github.freya022.botcommands.internal.commands.ratelimit.CancellableRateLimitImpl import io.github.freya022.botcommands.internal.commands.ratelimit.NullCancellableRateLimit @@ -28,7 +27,7 @@ internal class RateLimitHandler internal constructor( private val context: BContext, private val botOwners: BotOwners, private val rateLimitContainer: RateLimitContainer, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, config: BConfig, ) { private val enableOwnerBypass = config.enableOwnerBypass @@ -91,8 +90,7 @@ internal class RateLimitHandler internal constructor( val rateLimitInfo = rateLimitContainer[group] ?: run { componentsListenerLogger.warn { "Could not find a rate limiter named '$group'" } - val defaultMessages = defaultMessagesFactory.get(event) - event.reply_(defaultMessages.componentExpiredErrorMsg, ephemeral = true).queue() + event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() return } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt index f761a19e5..92c3d96b3 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt @@ -7,6 +7,7 @@ import io.github.freya022.botcommands.api.commands.text.annotations.RequiresText import io.github.freya022.botcommands.api.commands.text.provider.TextCommandManager import io.github.freya022.botcommands.api.commands.text.provider.TextCommandProvider import io.github.freya022.botcommands.api.core.config.BTextConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -14,7 +15,6 @@ import io.github.freya022.botcommands.api.core.service.annotations.ConditionalSe import io.github.freya022.botcommands.api.core.service.getInterfacedServices import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.* -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.commands.text.TextUtils.getSpacedPath import io.github.freya022.botcommands.internal.core.BContextImpl import io.github.freya022.botcommands.internal.utils.reference @@ -44,14 +44,14 @@ internal open class BuiltInHelpCommandProvider { @ConditionalOnMissingBean(IHelpCommand::class) internal open fun builtInHelpCommand( context: BContextImpl, - defaultMessagesFactory: DefaultMessagesFactory, + builtinRepliesFactory: BuiltinRepliesFactory, textCommandsContext: TextCommandsContext, helpBuilderConsumer: HelpBuilderConsumer?, - ) = HelpCommand(context, defaultMessagesFactory, textCommandsContext, helpBuilderConsumer) + ) = HelpCommand(context, builtinRepliesFactory, textCommandsContext, helpBuilderConsumer) } internal class HelpCommand internal constructor( private val context: BContextImpl, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val textCommandsContext: TextCommandsContext, private val helpBuilderConsumer: HelpBuilderConsumer? ) : IHelpCommand, TextCommandProvider { @@ -118,7 +118,7 @@ internal class HelpCommand internal constructor( // Ignore and reply in channel/react if we can't send to DMs .handle(ErrorResponse.CANNOT_SEND_TO_USER) { if (event.channel.canTalk()) - event.respond(defaultMessagesFactory.get(event).closedDMErrorMsg).await() + event.channel.sendMessage(builtinRepliesFactory.get(event).closedDirectMessages(event)).await() else if (hasReactionPermissions) // May throw REACTION_BLOCKED event.message.addReaction(context.textConfig.dmClosedEmoji).await() diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt index 493a42b3a..82fabd381 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt @@ -10,6 +10,8 @@ import io.github.freya022.botcommands.api.core.JDAService import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BTextConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -17,7 +19,6 @@ import io.github.freya022.botcommands.api.core.service.annotations.ConditionalSe import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.service.getServiceOrNull import io.github.freya022.botcommands.api.core.utils.* -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.commands.ratelimit.handler.RateLimitHandler import io.github.freya022.botcommands.internal.commands.text.TextCommandsListener.Status.* import io.github.freya022.botcommands.internal.core.ExceptionHandler @@ -32,6 +33,7 @@ import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.exceptions.InsufficientPermissionException import net.dv8tion.jda.api.requests.ErrorResponse import net.dv8tion.jda.api.requests.GatewayIntent +import net.dv8tion.jda.api.utils.messages.MessageCreateData private val logger = KotlinLogging.logger { } private val spacePattern = Regex("\\s+") @@ -42,7 +44,7 @@ private val spacePattern = Regex("\\s+") @ConditionalService(TextCommandsListener.ActivationCondition::class) internal class TextCommandsListener internal constructor( private val context: BContext, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val textCommandsContext: TextCommandsContextImpl, private val localizableTextCommandFactory: LocalizableTextCommandFactory, private val rateLimitHandler: RateLimitHandler, @@ -132,9 +134,9 @@ internal class TextCommandsListener internal constructor( private suspend fun handleException(event: MessageReceivedEvent, e: Throwable, msg: String) { exceptionHandler.handleException(event, e, "text command '$msg'", mapOf("Message" to event.jumpUrl)) if (e is InsufficientPermissionException) { - replyError(event, defaultMessagesFactory.get(event).getBotPermErrorMsg(setOf(e.permission))) + replyError(event, builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - replyError(event, defaultMessagesFactory.get(event).generalErrorMsg) + replyError(event, builtinRepliesFactory.get(event).uncaughtException(event)) } } @@ -175,19 +177,22 @@ internal class TextCommandsListener internal constructor( val usability = commandInfo.getUsability(member, event.guildChannel) if (usability.isNotUsable) { - val errorMessage: String = when (usability.bestReason) { - UnusableReason.HIDDEN -> throwInternal("Hidden commands should have been ignored by ${TextCommandsListener::findCommandWithArgs.shortSignature}") - UnusableReason.OWNER_ONLY -> defaultMessagesFactory.get(event).ownerOnlyErrorMsg - UnusableReason.USER_PERMISSIONS -> { - val missingPermissions = getMissingPermissions(commandInfo.userPermissions, member, event.guildChannel) - defaultMessagesFactory.get(event).getUserPermErrorMsg(missingPermissions) - } - UnusableReason.BOT_PERMISSIONS -> { - val missingPermissions = getMissingPermissions(commandInfo.botPermissions, event.guild.selfMember, event.guildChannel) - defaultMessagesFactory.get(event).getBotPermErrorMsg(missingPermissions) + val errorMessage = fromReplies(event) { + when (usability.bestReason) { + UnusableReason.HIDDEN -> throwInternal("Hidden commands should have been ignored by ${TextCommandsListener::findCommandWithArgs.shortSignature}") + UnusableReason.OWNER_ONLY -> ownerOnly(event) + UnusableReason.USER_PERMISSIONS -> { + val missingPermissions = getMissingPermissions(commandInfo.userPermissions, member, event.guildChannel) + missingUserPermissions(event, missingPermissions) + } + UnusableReason.BOT_PERMISSIONS -> { + val missingPermissions = getMissingPermissions(commandInfo.botPermissions, event.guild.selfMember, event.guildChannel) + missingBotPermissions(event, missingPermissions) + } + UnusableReason.NSFW_ONLY -> nsfwOnly(event) } - UnusableReason.NSFW_ONLY -> defaultMessagesFactory.get(event).nsfwOnlyErrorMsg } + replyError(event, errorMessage) return false } @@ -218,13 +223,13 @@ internal class TextCommandsListener internal constructor( return ExecutionResult.OK } - private suspend fun replyError(event: MessageReceivedEvent, msg: String) { + private suspend fun replyError(event: MessageReceivedEvent, message: MessageCreateData) { val channel = when { event.guildChannel.canTalk() -> event.channel else -> event.author.openPrivateChannel().await() } - channel.sendMessage(msg) + channel.sendMessage(message) .awaitCatching() .handle(ErrorResponse.CANNOT_SEND_TO_USER) { event.message.addReaction(context.textConfig.dmClosedEmoji).await() @@ -240,11 +245,14 @@ internal class TextCommandsListener internal constructor( val suggestions = suggestionSupplier.getSuggestions(commandName, candidates) if (suggestions.isNotEmpty()) { - val suggestionsStr = suggestions.joinToString("**, **", "**", "**") { it.name } - replyError(event, defaultMessagesFactory.get(event).getCommandNotFoundMsg(suggestionsStr)) + replyError(event, builtinRepliesFactory.get(event).commandNotFound(event, suggestions)) } } + private inline fun fromReplies(event: MessageReceivedEvent, crossinline block: BuiltinReplies.() -> MessageCreateData): MessageCreateData { + return builtinRepliesFactory.get(event).run(block) + } + internal enum class Status { /** Disabled by config */ DISABLED, diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt index 20b1fac4e..246ab3c39 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt @@ -1,6 +1,5 @@ package io.github.freya022.botcommands.internal.components.controller -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimit import io.github.freya022.botcommands.api.components.ComponentInteractionFilter import io.github.freya022.botcommands.api.components.Components @@ -13,9 +12,9 @@ import io.github.freya022.botcommands.api.core.Filter import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BComponentsConfigBuilder +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.commands.ratelimit.handler.RateLimitHandler import io.github.freya022.botcommands.internal.components.data.ActionComponentData import io.github.freya022.botcommands.internal.components.data.PersistentComponentData @@ -36,7 +35,7 @@ private val logger = KotlinLogging.logger { } @RequiresComponents internal class ComponentsListener( private val context: BContext, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val rateLimitHandler: RateLimitHandler, filters: List, @@ -61,13 +60,13 @@ internal class ComponentsListener( ComponentController.parseComponentId(id) } val component = componentController.getActiveComponent(componentId) - ?: return@launch event.reply_(defaultMessagesFactory.get(event).componentExpiredErrorMsg, ephemeral = true).queue() + ?: return@launch event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() if (component !is ActionComponentData) throwInternal("Somehow retrieved a non-executable component on a component interaction: $component") if (component.filters === ComponentFilters.INVALID_FILTERS) { - return@launch event.reply_(defaultMessagesFactory.get(event).componentNotAllowedErrorMsg, ephemeral = true).queue() + return@launch event.reply(builtinRepliesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() } component.filters.onEach { filter -> @@ -101,7 +100,7 @@ internal class ComponentsListener( component: ActionComponentData ): Boolean { if (!component.constraints.isAllowed(event)) { - event.reply_(defaultMessagesFactory.get(event).componentNotAllowedErrorMsg, ephemeral = true).queue() + event.reply(builtinRepliesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() return false } @@ -139,9 +138,9 @@ internal class ComponentsListener( "Component" to event.component )) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(defaultMessagesFactory.get(event).getBotPermErrorMsg(setOf(e.permission))) + event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(defaultMessagesFactory.get(event).generalErrorMsg) + event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt index 61b2ffe05..efcd36309 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt @@ -1,15 +1,14 @@ package io.github.freya022.botcommands.internal.components.handler -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.components.annotations.JDAButtonListener import io.github.freya022.botcommands.api.components.annotations.JDASelectMenuListener import io.github.freya022.botcommands.api.components.annotations.RequiresComponents import io.github.freya022.botcommands.api.components.event.EntitySelectEvent import io.github.freya022.botcommands.api.components.event.StringSelectEvent import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.internal.components.ComponentType import io.github.freya022.botcommands.internal.components.data.ActionComponentData import io.github.freya022.botcommands.internal.components.data.EphemeralComponentData @@ -33,7 +32,7 @@ private val logger = KotlinLogging.logger { } @BService @RequiresComponents internal class ComponentHandlerExecutor internal constructor( - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val componentHandlerContainer: ComponentHandlerContainer, ) { internal suspend fun runHandler(component: ActionComponentData, event: GenericComponentInteractionCreateEvent): Boolean { @@ -61,7 +60,7 @@ internal class ComponentHandlerExecutor internal constructor( Component raw data: $userData """.trimIndent() } - event.reply_(defaultMessagesFactory.get(event).componentExpiredErrorMsg, ephemeral = true).queue() + event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() return false } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt index 6e6922637..a318d2579 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt @@ -1,10 +1,9 @@ package io.github.freya022.botcommands.internal.modals -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.config.BModalsConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.modals.ModalEvent import io.github.freya022.botcommands.api.modals.Modals import io.github.freya022.botcommands.api.modals.annotations.ModalHandler @@ -24,7 +23,7 @@ private val logger = KotlinLogging.logger { } @RequiresModals internal class ModalListener( private val context: BContextImpl, - private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val modalHandlerContainer: ModalHandlerContainer, private val modalMaps: ModalMaps, @@ -44,7 +43,7 @@ internal class ModalListener( val modalData = modalMaps.consumeModal(ModalMaps.parseModalId(jdaEvent.modalId)) if (modalData == null) { //Probably the modal expired - jdaEvent.reply_(defaultMessagesFactory.get(jdaEvent).modalExpiredErrorMsg, ephemeral = true).queue() + jdaEvent.reply(builtinRepliesFactory.get(jdaEvent).modalExpired(jdaEvent)).setEphemeral(true).queue() return@launch } @@ -73,9 +72,9 @@ internal class ModalListener( put("Modal values", event.values.associate { it.id to it.asString }) }) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(defaultMessagesFactory.get(event).getBotPermErrorMsg(setOf(e.permission))) + event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(defaultMessagesFactory.get(event).generalErrorMsg) + event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt index ebc2a4bda..8a3d58584 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt @@ -1,6 +1,5 @@ package io.github.freya022.botcommands.internal.parameters.resolvers -import dev.minn.jda.ktx.messages.reply_ import io.github.freya022.botcommands.api.commands.application.context.user.options.UserContextCommandOption import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.BaseCommandEvent @@ -8,11 +7,11 @@ import io.github.freya022.botcommands.api.commands.text.options.TextCommandOptio import io.github.freya022.botcommands.api.components.options.ComponentOption import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData import io.github.freya022.botcommands.api.core.BContext +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.traceNull import io.github.freya022.botcommands.api.core.utils.retrieveMemberByIdOrNull import io.github.freya022.botcommands.api.core.utils.retrieveUserByIdOrNull -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.parameters.ClassParameterResolver import io.github.freya022.botcommands.api.parameters.resolvers.ComponentParameterResolver import io.github.freya022.botcommands.api.parameters.resolvers.SlashParameterResolver @@ -41,8 +40,8 @@ internal sealed class AbstractUserSnowflakeResolver, ComponentParameterResolver, UserContextParameterResolver { - - private val defaultMessagesFactory: DefaultMessagesFactory = context.getService() + + private val builtinRepliesFactory: BuiltinRepliesFactory = context.getService() final override val pattern: Pattern get() = userMentionPattern final override val testExample: String = "<@1234>" @@ -76,7 +75,7 @@ internal sealed class AbstractUserSnowflakeResolver")).queue() + event.message.reply(builtinRepliesFactory.get(event).resolverChannelMissingAccess(event, channelId)).queue() }) private suspend fun retrieveThreadChannel( - event: IReplyCallback, + event: GenericComponentInteractionCreateEvent, guild: Guild, channelId: Long ): ThreadChannel? = retrieveThreadChannel(guild, channelId, onMissingAccess = { - event.reply_(defaultMessagesFactory.get(event).getResolverChannelMissingAccessMsg("<#$channelId>"), ephemeral = true).queue() + event.reply(builtinRepliesFactory.get(event).resolverChannelMissingAccess(event, channelId)).queue() }) private suspend fun retrieveThreadChannel( diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/utils/Exceptions.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/utils/Exceptions.kt index 4d16c975d..3fd7319a4 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/utils/Exceptions.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/utils/Exceptions.kt @@ -9,6 +9,7 @@ import kotlinx.datetime.Clock import kotlinx.datetime.Instant import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback import net.dv8tion.jda.api.requests.ErrorResponse +import net.dv8tion.jda.api.utils.messages.MessageCreateData import java.lang.reflect.InvocationTargetException import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -138,7 +139,7 @@ internal fun Throwable.unwrap(): Throwable { } internal suspend fun IReplyCallback.replyExceptionMessage( - message: String + message: MessageCreateData ) = runIgnoringResponse(ErrorResponse.UNKNOWN_INTERACTION, ErrorResponse.UNKNOWN_WEBHOOK) { if (isAcknowledged) { // Give ourselves 5 seconds to delete From 54b2b1bf4477a558363da61a405edd686be78040 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sat, 21 Jun 2025 14:05:51 +0200 Subject: [PATCH 02/21] Add BuiltinRepliesFactory provider --- .../BuiltinRepliesDefaultMessagesAdapter.kt | 91 +++++++++++++++++++ ...iesFactoryDefaultMessagesFactoryAdapter.kt | 25 +++++ .../replies/BuiltinRepliesFactoryProvider.kt | 72 +++++++++++++++ .../DefaultDefaultMessagesFactoryProvider.kt | 26 +----- .../FallbackDefaultMessagesFactory.kt | 30 ++++++ .../bc_localization/DefaultMessages.json | 3 - .../bc_localization/DefaultMessages_fr.json | 3 - 7 files changed, 219 insertions(+), 31 deletions(-) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt delete mode 100644 src/test/resources/bc_localization/DefaultMessages.json delete mode 100644 src/test/resources/bc_localization/DefaultMessages_fr.json diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt new file mode 100644 index 000000000..7305eff57 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt @@ -0,0 +1,91 @@ +package io.github.freya022.botcommands.internal.core.replies + +import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption +import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.localization.DefaultMessages +import net.dv8tion.jda.api.Permission +import net.dv8tion.jda.api.events.GenericEvent +import net.dv8tion.jda.api.utils.TimeFormat +import net.dv8tion.jda.api.utils.messages.MessageCreateData +import java.time.Instant + +internal class BuiltinRepliesDefaultMessagesAdapter internal constructor( + private val defaultMessages: DefaultMessages, +) : BuiltinReplies { + + override fun uncaughtException(event: GenericEvent?): MessageCreateData { + return defaultMessages.generalErrorMsg.toMessage() + } + + override fun missingUserPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { + return defaultMessages.getUserPermErrorMsg(permissions).toMessage() + } + + override fun missingBotPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { + return defaultMessages.getBotPermErrorMsg(permissions).toMessage() + } + + override fun ownerOnly(event: GenericEvent?): MessageCreateData { + return defaultMessages.ownerOnlyErrorMsg.toMessage() + } + + override fun userRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + return defaultMessages.getUserRateLimitMsg(TimeFormat.RELATIVE.atInstant(deadline)).toMessage() + } + + override fun channelRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + return defaultMessages.getChannelRateLimitMsg(TimeFormat.RELATIVE.atInstant(deadline)).toMessage() + } + + override fun guildRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData { + return defaultMessages.getGuildRateLimitMsg(TimeFormat.RELATIVE.atInstant(deadline)).toMessage() + } + + override fun applicationCommandsNotAvailable(event: GenericEvent?): MessageCreateData { + return defaultMessages.applicationCommandsNotAvailableMsg.toMessage() + } + + override fun commandNotFound(event: GenericEvent?, suggestions: Collection): MessageCreateData { + val suggestionsStr = suggestions.joinToString(separator = "**, **", prefix = "**", postfix = "**") { it.name } + return defaultMessages.getCommandNotFoundMsg(suggestionsStr).toMessage() + } + + override fun resolverChannelNotFound(event: GenericEvent?, channelId: Long): MessageCreateData { + return defaultMessages.resolverChannelNotFoundMsg.toMessage() + } + + override fun resolverChannelMissingAccess(event: GenericEvent?, channelId: Long): MessageCreateData { + return defaultMessages.getResolverChannelMissingAccessMsg("<#$channelId>").toMessage() + } + + override fun resolverUserNotFound(event: GenericEvent?, userId: Long): MessageCreateData { + return defaultMessages.resolverUserNotFoundMsg.toMessage() + } + + override fun slashCommandUnresolvableOption(event: GenericEvent?, option: SlashCommandOption): MessageCreateData { + return defaultMessages.getSlashCommandUnresolvableOptionMsg(option.discordName).toMessage() + } + + override fun closedDirectMessages(event: GenericEvent?): MessageCreateData { + return defaultMessages.closedDMErrorMsg.toMessage() + } + + override fun nsfwOnly(event: GenericEvent?): MessageCreateData { + return defaultMessages.nsfwOnlyErrorMsg.toMessage() + } + + override fun componentNotAllowed(event: GenericEvent?): MessageCreateData { + return defaultMessages.componentNotAllowedErrorMsg.toMessage() + } + + override fun componentExpired(event: GenericEvent?): MessageCreateData { + return defaultMessages.componentExpiredErrorMsg.toMessage() + } + + override fun modalExpired(event: GenericEvent?): MessageCreateData { + return defaultMessages.modalExpiredErrorMsg.toMessage() + } + + private fun String.toMessage(): MessageCreateData = MessageCreateData.fromContent(this) +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt new file mode 100644 index 000000000..9716cc12f --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt @@ -0,0 +1,25 @@ +package io.github.freya022.botcommands.internal.core.replies + +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import java.util.* + +internal class BuiltinRepliesFactoryDefaultMessagesFactoryAdapter internal constructor( + private val defaultMessagesFactory: DefaultMessagesFactory, +) : BuiltinRepliesFactory { + + override fun get(locale: Locale): BuiltinReplies { + return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(locale)) + } + + override fun get(event: MessageReceivedEvent): BuiltinReplies { + return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) + } + + override fun get(event: Interaction): BuiltinReplies { + return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt new file mode 100644 index 000000000..7ec6c1934 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt @@ -0,0 +1,72 @@ +package io.github.freya022.botcommands.internal.core.replies + +import io.github.classgraph.ClassGraph +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.DefaultBuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker +import io.github.freya022.botcommands.api.core.service.ServiceContainer +import io.github.freya022.botcommands.api.core.service.annotations.BService +import io.github.freya022.botcommands.api.core.service.annotations.ConditionalService +import io.github.freya022.botcommands.api.core.service.getInterfacedServiceTypes +import io.github.freya022.botcommands.api.core.utils.simpleNestedName +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider +import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider +import io.github.freya022.botcommands.internal.localization.FallbackDefaultMessagesFactory +import io.github.freya022.botcommands.internal.utils.classRef +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.boot.autoconfigure.AutoConfiguration +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.context.annotation.Bean + +private val logger = KotlinLogging.logger { } + +@AutoConfiguration +@ConditionalOnMissingBean(BuiltinRepliesFactory::class) +@BService +internal open class BuiltinRepliesFactoryProvider internal constructor() { + + @Bean + @BService + @ConditionalService(ActivationCondition::class) + open fun builtinRepliesFactory( + defaultMessagesFactory: DefaultMessagesFactory, + localizationService: LocalizationService, + textCommandLocaleProvider: TextCommandLocaleProvider, + userLocaleProvider: UserLocaleProvider, + ): BuiltinRepliesFactory { + // Check if the user has a custom factory or if the fallback factory has customized files + if (defaultMessagesFactory !is FallbackDefaultMessagesFactory || hasCustomDefaultMessages()) { + logger.warn { "${classRef()} has been deprecated and will be removed in the full release." } + return BuiltinRepliesFactoryDefaultMessagesFactoryAdapter(defaultMessagesFactory) + } + + return DefaultBuiltinRepliesFactory(localizationService, textCommandLocaleProvider, userLocaleProvider) + } + + private fun hasCustomDefaultMessages(): Boolean { + // The base name is guaranteed to be "DefaultMessages" as it is hardcoded in [[DefaultMessages]] + return ClassGraph() + .acceptPathsNonRecursive("bc_localization") + .scan() + .use { scan -> + scan.allResources + .any { + val path = it.path + path.startsWith("bc_localization/DefaultMessages") && !path.startsWith("bc_localization/DefaultMessages-default") + } + } + } + + internal object ActivationCondition : ConditionalServiceChecker { + override fun checkServiceAvailability(serviceContainer: ServiceContainer, checkedClass: Class<*>): String? { + val types = serviceContainer.getInterfacedServiceTypes() + if (types.isNotEmpty()) { + return "An user supplied ${classRef()} is already active (${types.first().simpleNestedName})" + } + + return null + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt index 0572fef42..21538296d 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt @@ -6,18 +6,14 @@ import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.service.annotations.ConditionalService import io.github.freya022.botcommands.api.core.service.getInterfacedServiceTypes import io.github.freya022.botcommands.api.core.utils.simpleNestedName -import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider import io.github.freya022.botcommands.internal.utils.classRef -import net.dv8tion.jda.api.events.message.MessageReceivedEvent -import net.dv8tion.jda.api.interactions.Interaction import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import java.util.* // I hate those names @Configuration @@ -31,27 +27,7 @@ internal open class DefaultDefaultMessagesFactoryProvider { localizationService: LocalizationService, textCommandLocaleProvider: TextCommandLocaleProvider, userLocaleProvider: UserLocaleProvider, - ): DefaultMessagesFactory = DefaultDefaultMessagesFactory(localizationService, textCommandLocaleProvider, userLocaleProvider) - - private class DefaultDefaultMessagesFactory( - private val localizationService: LocalizationService, - private val textCommandLocaleProvider: TextCommandLocaleProvider, - private val userLocaleProvider: UserLocaleProvider, - ): DefaultMessagesFactory { - private val localeDefaultMessagesMap: MutableMap = hashMapOf() - - override fun get(locale: Locale): DefaultMessages = localeDefaultMessagesMap.computeIfAbsent(locale) { - DefaultMessages(localizationService, it) - } - - override fun get(event: MessageReceivedEvent): DefaultMessages { - return get(textCommandLocaleProvider.getLocale(event)) - } - - override fun get(event: Interaction): DefaultMessages { - return get(userLocaleProvider.getLocale(event)) - } - } + ): DefaultMessagesFactory = FallbackDefaultMessagesFactory(localizationService, textCommandLocaleProvider, userLocaleProvider) internal object ActivationCondition : ConditionalServiceChecker { override fun checkServiceAvailability(serviceContainer: ServiceContainer, checkedClass: Class<*>): String? { diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt new file mode 100644 index 000000000..6a368e150 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt @@ -0,0 +1,30 @@ +package io.github.freya022.botcommands.internal.localization + +import io.github.freya022.botcommands.api.localization.DefaultMessages +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider +import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import java.util.* + +internal class FallbackDefaultMessagesFactory internal constructor( + private val localizationService: LocalizationService, + private val textCommandLocaleProvider: TextCommandLocaleProvider, + private val userLocaleProvider: UserLocaleProvider, +): DefaultMessagesFactory { + private val cache: MutableMap = hashMapOf() + + override fun get(locale: Locale): DefaultMessages = cache.computeIfAbsent(locale) { + DefaultMessages(localizationService, it) + } + + override fun get(event: MessageReceivedEvent): DefaultMessages { + return get(textCommandLocaleProvider.getLocale(event)) + } + + override fun get(event: Interaction): DefaultMessages { + return get(userLocaleProvider.getLocale(event)) + } +} \ No newline at end of file diff --git a/src/test/resources/bc_localization/DefaultMessages.json b/src/test/resources/bc_localization/DefaultMessages.json deleted file mode 100644 index 64c785130..000000000 --- a/src/test/resources/bc_localization/DefaultMessages.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "null.component.type.error.message": "Component go bruh :skull:" -} \ No newline at end of file diff --git a/src/test/resources/bc_localization/DefaultMessages_fr.json b/src/test/resources/bc_localization/DefaultMessages_fr.json deleted file mode 100644 index 8f169c4d4..000000000 --- a/src/test/resources/bc_localization/DefaultMessages_fr.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "null.component.type.error.message": "Ce composant n'est plus utilisable" -} \ No newline at end of file From 507d543a5cbad089e4ff34c650c963bf0567a1a2 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sat, 21 Jun 2025 14:08:44 +0200 Subject: [PATCH 03/21] Add LocalizableAction#getBuiltinReplies --- .../botcommands/api/localization/LocalizableAction.kt | 9 +++++++++ .../interaction/LocalizableInteractionFactory.kt | 4 +++- .../interaction/LocalizableInteractionImpl.kt | 7 +++++++ .../localization/text/LocalizableTextCommandFactory.kt | 4 +++- .../localization/text/LocalizableTextCommandImpl.kt | 7 +++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt index 257a4e262..4e7636a14 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt @@ -1,6 +1,8 @@ package io.github.freya022.botcommands.api.localization import io.github.freya022.botcommands.api.core.config.BLocalizationConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.localization.context.LocalizationContext import io.github.freya022.botcommands.api.localization.context.PairEntry import io.github.freya022.botcommands.api.localization.context.mapToEntries @@ -45,6 +47,13 @@ interface LocalizableAction { */ fun getDefaultMessages(): DefaultMessages + /** + * Retrieves a [BuiltinReplies] instance, using a locale suitable for messages sent to the user. + * + * @see BuiltinRepliesFactory + */ + fun getBuiltinReplies(): BuiltinReplies + /** * Returns the localized message at the following [path][localizationPath], * using the provided locale and parameters. diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt index 58ac8dd18..1e071f86b 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt @@ -1,6 +1,7 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService @@ -16,7 +17,8 @@ internal class LocalizableInteractionFactory internal constructor( private val userLocaleProvider: UserLocaleProvider, private val guildLocaleProvider: GuildLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, ) { internal fun create(event: IReplyCallback) = - LocalizableInteractionImpl(event, localizationService, localizationConfig, userLocaleProvider, guildLocaleProvider, defaultMessagesFactory) + LocalizableInteractionImpl(event, localizationService, localizationConfig, userLocaleProvider, guildLocaleProvider, defaultMessagesFactory, builtinRepliesFactory) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt index 594a18438..8f10c6a11 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt @@ -1,6 +1,8 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization @@ -22,6 +24,7 @@ internal class LocalizableInteractionImpl internal constructor( private val userLocaleProvider: UserLocaleProvider, private val guildLocaleProvider: GuildLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, ) : AbstractLocalizableAction(localizationConfig, localizationService), LocalizableInteraction { @@ -42,6 +45,10 @@ internal class LocalizableInteractionImpl internal constructor( return defaultMessagesFactory.get(deferrableCallback) } + override fun getBuiltinReplies(): BuiltinReplies { + return builtinRepliesFactory.get(deferrableCallback) + } + override fun getUserMessage(localizationPath: String, vararg entries: Localization.Entry): String { return getLocalizedMessage(userLocale, localizationPath, *entries) } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt index 665fda414..f791da684 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt @@ -1,6 +1,7 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService @@ -14,7 +15,8 @@ internal class LocalizableTextCommandFactory internal constructor( private val localizationConfig: BLocalizationConfig, private val localeProvider: TextCommandLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, ) { internal fun create(event: MessageReceivedEvent) = - LocalizableTextCommandImpl(event, localizationService, localizationConfig, localeProvider, defaultMessagesFactory) + LocalizableTextCommandImpl(event, localizationService, localizationConfig, localeProvider, defaultMessagesFactory, builtinRepliesFactory) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt index 4be783a7f..07e3b0cda 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt @@ -1,6 +1,8 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization @@ -20,6 +22,7 @@ internal class LocalizableTextCommandImpl internal constructor( localizationConfig: BLocalizationConfig, private val localeProvider: TextCommandLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, + private val builtinRepliesFactory: BuiltinRepliesFactory, ) : AbstractLocalizableAction(localizationConfig, localizationService), LocalizableTextCommand { private val locale: Locale by lazy { localeProvider.getLocale(event) } @@ -36,6 +39,10 @@ internal class LocalizableTextCommandImpl internal constructor( return defaultMessagesFactory.get(locale) } + override fun getBuiltinReplies(): BuiltinReplies { + return builtinRepliesFactory.get(locale) + } + override fun getGuildMessage(localizationPath: String, vararg entries: Localization.Entry): String { return getLocalizedMessage(locale, localizationPath, *entries) } From eb1c82b4ebef870c8f072ff4d7fd04aa1b3be484 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sat, 21 Jun 2025 16:44:57 +0200 Subject: [PATCH 04/21] Deprecate DefaultMessages[Factory] --- .../botcommands/api/localization/DefaultMessages.java | 3 +++ .../commands/ratelimit/handler/DefaultRateLimitHandler.kt | 3 +-- .../freya022/botcommands/api/core/config/BTextConfig.kt | 4 ++-- .../botcommands/api/core/replies/BuiltinRepliesFactory.kt | 2 ++ .../io/github/freya022/botcommands/api/core/utils/JDA.kt | 2 ++ .../botcommands/api/localization/DefaultMessagesFactory.kt | 3 +++ .../botcommands/api/localization/LocalizableAction.kt | 2 ++ .../api/parameters/resolvers/SlashParameterResolver.kt | 6 +++--- .../core/replies/BuiltinRepliesDefaultMessagesAdapter.kt | 2 ++ .../BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt | 2 ++ .../internal/core/replies/BuiltinRepliesFactoryProvider.kt | 2 ++ .../localization/DefaultDefaultMessagesFactoryProvider.kt | 2 ++ .../internal/localization/FallbackDefaultMessagesFactory.kt | 2 ++ .../interaction/LocalizableInteractionFactory.kt | 2 ++ .../localization/interaction/LocalizableInteractionImpl.kt | 4 ++++ .../localization/text/LocalizableTextCommandFactory.kt | 2 ++ .../localization/text/LocalizableTextCommandImpl.kt | 4 ++++ 17 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java index 041965fcd..5c547cc4d 100644 --- a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java +++ b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java @@ -42,7 +42,10 @@ *

Refer to {@link Localization} for more details. * * @see Localization + * + * @deprecated This has been replaced by {@link io.github.freya022.botcommands.api.core.replies.DefaultBuiltinReplies DefaultBuiltinReplies} */ +@Deprecated(since = "3.1.0-beta.1", forRemoval = true) public final class DefaultMessages { private final Localization localization; diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt index 9930a0473..630f6c05e 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt @@ -13,7 +13,6 @@ import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.awaitCatching import io.github.freya022.botcommands.api.core.utils.namedDefaultScope import io.github.freya022.botcommands.api.core.utils.runIgnoringResponse -import io.github.freya022.botcommands.api.localization.DefaultMessages import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel @@ -39,7 +38,7 @@ private val deleteScope = namedDefaultScope("Rate limit message delete", 1) * then it is sent to the user's DMs, or returns if not possible. * - Interactions are simply replying an ephemeral message to the user. * - * All messages sent to the user are localized messages from [DefaultMessages] and will be deleted when expired. + * All messages sent to the user are localized messages from [BuiltinReplies] and will be deleted when expired. * * **Note:** The rate limit message won't be deleted in a private channel, * or if the [refill delay][ConsumptionProbe.nanosToWaitForRefill] is longer than 10 minutes. diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt index a54815765..4ffb0f5b5 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt @@ -4,9 +4,9 @@ import dev.freya02.jda.emojis.unicode.Emojis import io.github.freya022.botcommands.api.commands.text.IHelpCommand import io.github.freya022.botcommands.api.commands.text.TextPrefixSupplier import io.github.freya022.botcommands.api.commands.text.annotations.RequiresTextCommands +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies import io.github.freya022.botcommands.api.core.service.annotations.InjectedService import io.github.freya022.botcommands.api.core.utils.toImmutableList -import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.internal.core.config.ConfigDSL import io.github.freya022.botcommands.internal.core.config.ConfigurationValue import net.dv8tion.jda.api.entities.emoji.Emoji @@ -78,7 +78,7 @@ interface BTextConfig { /** * Emoji used to indicate a user that their DMs are closed. * - * This is only used if [the closed DMs error message][DefaultMessages.getClosedDMErrorMsg] can't be sent. + * This is only used if [the closed DMs error message][BuiltinReplies.closedDirectMessages] can't be sent. * * Default: `mailbox_closed` * diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt index cd9f279d0..cbb6c6d70 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package io.github.freya022.botcommands.api.core.replies import io.github.freya022.botcommands.api.core.service.annotations.BService diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt index 8696177c5..a9eb76309 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.api.core.utils import dev.minn.jda.ktx.coroutines.await diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt index 0b2064aa7..ffed5faae 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.api.localization import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -15,6 +17,7 @@ import java.util.* * * @see InterfacedService @InterfacedService */ +@Deprecated("Replaced by BuiltinRepliesFactory") @InterfacedService(acceptMultiple = false) interface DefaultMessagesFactory { /** diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt index 4e7636a14..e847c04e7 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt @@ -45,6 +45,8 @@ interface LocalizableAction { * * @see DefaultMessagesFactory */ + @Suppress("DEPRECATION", "removal") + @Deprecated("Replaced with getBuiltinReplies()") fun getDefaultMessages(): DefaultMessages /** diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt index 1ed134d94..5098383a5 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt @@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.commands.application.slash.annotations import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.annotations.AutocompleteHandler import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.application.slash.options.builder.SlashCommandOptionBuilder -import io.github.freya022.botcommands.api.localization.DefaultMessages +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies import io.github.freya022.botcommands.api.parameters.ParameterResolver import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent @@ -57,7 +57,7 @@ interface SlashParameterResolver : IParameterResolver * and you should reply if this is a [SlashCommandInteractionEvent]. * * If the interaction is not replied to, - * the handler sends an [unresolvable option error message][DefaultMessages.getSlashCommandUnresolvableOptionMsg]. + * the handler sends an [unresolvable option error message][BuiltinReplies.slashCommandUnresolvableOption]. * * @param option The option currently being resolved * @param event The corresponding event, could be a [SlashCommandInteractionEvent] or a [CommandAutoCompleteInteractionEvent] @@ -74,7 +74,7 @@ interface SlashParameterResolver : IParameterResolver * and you should reply if this is a [SlashCommandInteractionEvent]. * * If the interaction is not replied to, - * the handler sends an [unresolvable option error message][DefaultMessages.getSlashCommandUnresolvableOptionMsg]. + * the handler sends an [unresolvable option error message][BuiltinReplies.slashCommandUnresolvableOption]. * * @param option The option currently being resolved * @param event The corresponding event, could be a [SlashCommandInteractionEvent] or a [CommandAutoCompleteInteractionEvent] diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt index 7305eff57..acfdcb639 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.core.replies import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt index 9716cc12f..44dd5c032 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.core.replies import io.github.freya022.botcommands.api.core.replies.BuiltinReplies diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt index 7ec6c1934..3ed05fa9b 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package io.github.freya022.botcommands.internal.core.replies import io.github.classgraph.ClassGraph diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt index 21538296d..fe33f4b4e 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/DefaultDefaultMessagesFactoryProvider.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.localization import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt index 6a368e150..e63776722 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/FallbackDefaultMessagesFactory.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.localization import io.github.freya022.botcommands.api.localization.DefaultMessages diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt index 1e071f86b..3b823dc6a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt index 8f10c6a11..9abc5efbe 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig @@ -41,6 +43,8 @@ internal class LocalizableInteractionImpl internal constructor( ) } + @Suppress("DEPRECATION", "removal") + @Deprecated("Replaced with getBuiltinReplies()") override fun getDefaultMessages(): DefaultMessages { return defaultMessagesFactory.get(deferrableCallback) } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt index f791da684..26aa8ab9a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt index 07e3b0cda..376c9fab0 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt @@ -1,3 +1,5 @@ +@file:Suppress("removal", "DEPRECATION") + package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig @@ -35,6 +37,8 @@ internal class LocalizableTextCommandImpl internal constructor( ) } + @Suppress("DEPRECATION", "removal") + @Deprecated("Replaced with getBuiltinReplies()") override fun getDefaultMessages(): DefaultMessages { return defaultMessagesFactory.get(locale) } From 91fb48fa5cb02c4b8c26ef3313c6da59363d0ba7 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sat, 21 Jun 2025 19:17:21 +0200 Subject: [PATCH 05/21] Move docs --- .../botcommands/api/core/replies/BuiltinRepliesFactory.kt | 7 +++++-- .../api/core/replies/DefaultBuiltinRepliesFactory.kt | 6 ------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt index cbb6c6d70..39af6991a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt @@ -2,7 +2,6 @@ package io.github.freya022.botcommands.api.core.replies -import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider @@ -15,7 +14,11 @@ import java.util.* * Factory of [BuiltinReplies], the default implementation is [DefaultBuiltinRepliesFactory], or, * if a non-default [DefaultMessagesFactory] exists, an adapter is used. * - * **Usage**: Register your instance as a service with [@BService][BService]. + * ### Complete customization + * + * Returning a [BuiltinRepliesFactory] from a service factory will disable the default implementation, + * this will let you return a completely custom instance, + * in which you can craft entirely custom messages in any way you see fit. */ @InterfacedService(acceptMultiple = false) interface BuiltinRepliesFactory { diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt index 99c023987..2b2002cf0 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt @@ -31,12 +31,6 @@ import kotlin.concurrent.withLock * * Refer to [Localization] for mode customization details. * - * ### Complete customization - * - * Returning a [BuiltinRepliesFactory] from a service factory will disable the default implementation, - * this will let you return a completely custom instance, - * in which you can craft entirely custom messages in any way you see fit. - * * @see Localization */ class DefaultBuiltinRepliesFactory( From dd05160712b6f8406242a77e6cb603626b034d53 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sat, 21 Jun 2025 19:21:56 +0200 Subject: [PATCH 06/21] Add PermissionLocalization --- .../api/core/replies/DefaultBuiltinReplies.kt | 16 +++---- .../replies/DefaultBuiltinRepliesFactory.kt | 4 +- .../DefaultPermissionLocalization.kt | 44 +++++++++++++++++++ .../localization/PermissionLocalization.kt | 21 +++++++++ .../replies/BuiltinRepliesFactoryProvider.kt | 4 +- .../PermissionLocalizationProvider.kt | 39 ++++++++++++++++ 6 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultPermissionLocalization.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/localization/PermissionLocalization.kt create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt index 967dc762d..aa0a52eb5 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt @@ -5,6 +5,7 @@ import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService import io.github.freya022.botcommands.api.localization.LocalizationTemplate +import io.github.freya022.botcommands.api.localization.PermissionLocalization import io.github.freya022.botcommands.api.localization.localize import io.github.freya022.botcommands.internal.utils.throwArgument import net.dv8tion.jda.api.Permission @@ -13,6 +14,7 @@ import net.dv8tion.jda.api.utils.TimeFormat import net.dv8tion.jda.api.utils.messages.MessageCreateData import java.time.Instant import java.util.* +import kotlin.to /** * Default implementation of [BuiltinReplies], @@ -21,8 +23,9 @@ import java.util.* * @see DefaultBuiltinRepliesFactory */ open class DefaultBuiltinReplies( + protected val permissionLocalization: PermissionLocalization, localizationService: LocalizationService, - locale: Locale, + protected val locale: Locale, bundleName: String, ) : BuiltinReplies { @@ -32,19 +35,17 @@ open class DefaultBuiltinReplies( throwArgument("Could find localization files for '$bundleName', providers: $mappingProviders, readers: $mappingReaders") } - protected val permissionsLocalization: Localization? = localizationService.getInstance("Permissions", locale) - override fun uncaughtException(event: GenericEvent?): MessageCreateData { return getLocalizationTemplate("uncaught_exception").localize().toMessage() } override fun missingUserPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { - val localizedPermissions = permissions.joinToString(separator = ", ", transform = ::getLocalizedPermission) + val localizedPermissions = permissions.joinToString(separator = ", ") { permissionLocalization.localize(it, locale) } return getLocalizationTemplate("missing.permissions.user").localize("permissions" to localizedPermissions).toMessage() } override fun missingBotPermissions(event: GenericEvent?, permissions: Set): MessageCreateData { - val localizedPermissions = permissions.joinToString(separator = ", ", transform = ::getLocalizedPermission) + val localizedPermissions = permissions.joinToString(separator = ", ") { permissionLocalization.localize(it, locale) } return getLocalizationTemplate("missing.permissions.bot").localize("permissions" to localizedPermissions).toMessage() } @@ -119,10 +120,5 @@ open class DefaultBuiltinReplies( return template } - protected fun getLocalizedPermission(permission: Permission): String { - @Suppress("UsePropertyAccessSyntax") // `permission.name` targets Enum#name() which is definitely not the same - return permissionsLocalization?.get(permission.name)?.localize() ?: permission.getName() - } - protected fun String.toMessage(): MessageCreateData = MessageCreateData.fromContent(this) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt index 2b2002cf0..180f5e928 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt @@ -2,6 +2,7 @@ package io.github.freya022.botcommands.api.core.replies import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.PermissionLocalization import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider import net.dv8tion.jda.api.events.message.MessageReceivedEvent @@ -34,6 +35,7 @@ import kotlin.concurrent.withLock * @see Localization */ class DefaultBuiltinRepliesFactory( + private val permissionLocalization: PermissionLocalization, private val localizationService: LocalizationService, private val textCommandLocaleProvider: TextCommandLocaleProvider, private val userLocaleProvider: UserLocaleProvider, @@ -47,7 +49,7 @@ class DefaultBuiltinRepliesFactory( cache[locale]?.let { return it } return lock.withLock { - cache.getOrPut(locale) { DefaultBuiltinReplies(localizationService, locale, bundleName) } + cache.getOrPut(locale) { DefaultBuiltinReplies(permissionLocalization, localizationService, locale, bundleName) } } } diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultPermissionLocalization.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultPermissionLocalization.kt new file mode 100644 index 000000000..20cc7ddd2 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultPermissionLocalization.kt @@ -0,0 +1,44 @@ +package io.github.freya022.botcommands.api.localization + +import net.dv8tion.jda.api.Permission +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +/** + * Default implementation for [PermissionLocalization]. + * + * The translations are queried from [bundleName], + * and the keys used are the enum name of the permission. + * + * The returned translations will try to use the nearest available locale, + * with the last fallback being [Permission.getName]. + * + * ### Light customization / Supporting more locales + * + * To support more locales, (here we supposed the [bundleName] is `Permissions`) you may create a new `Permissions.json` + * following by appending an underscore and the [language tag][Locale.toLanguageTag], + * such as `Permissions_fr.json`. + * + * The localization paths must be equal to [Permission.getName]. + * + * Refer to [Localization] for mode customization details. + */ +open class DefaultPermissionLocalization( + protected val localizationService: LocalizationService, + protected val bundleName: String = "Permissions", +) : PermissionLocalization { + + private val cache: MutableMap = ConcurrentHashMap() + + override fun localize(permission: Permission, locale: Locale): String { + val key = CacheKey(permission, locale) + return cache.getOrPut(key) { + val permissionsLocalization: Localization? = localizationService.getInstance(bundleName, locale) + + @Suppress("UsePropertyAccessSyntax") // `permission.name` targets Enum#name() which is definitely not the same + permissionsLocalization?.get(permission.name)?.localize() ?: permission.getName() + } + } + + private data class CacheKey(val permission: Permission, val locale: Locale) +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/PermissionLocalization.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/PermissionLocalization.kt new file mode 100644 index 000000000..c06b9b2dc --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/PermissionLocalization.kt @@ -0,0 +1,21 @@ +package io.github.freya022.botcommands.api.localization + +import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService +import net.dv8tion.jda.api.Permission +import java.util.* + +/** + * Utility service to translate [Permission] names, a [DefaultPermissionLocalization] instance is available by default, + * but can be overridden if necessary, using a service factory. + */ +@InterfacedService(acceptMultiple = false) +interface PermissionLocalization { + + /** + * Returns the given permission's name with the requested locale. + * + * If no translation is available for the requested locale, + * it is permitted to return fallbacks. + */ + fun localize(permission: Permission, locale: Locale): String +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt index 3ed05fa9b..3f58996dc 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt @@ -13,6 +13,7 @@ import io.github.freya022.botcommands.api.core.service.getInterfacedServiceTypes import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.PermissionLocalization import io.github.freya022.botcommands.api.localization.interaction.UserLocaleProvider import io.github.freya022.botcommands.api.localization.text.TextCommandLocaleProvider import io.github.freya022.botcommands.internal.localization.FallbackDefaultMessagesFactory @@ -34,6 +35,7 @@ internal open class BuiltinRepliesFactoryProvider internal constructor() { @ConditionalService(ActivationCondition::class) open fun builtinRepliesFactory( defaultMessagesFactory: DefaultMessagesFactory, + permissionLocalization: PermissionLocalization, localizationService: LocalizationService, textCommandLocaleProvider: TextCommandLocaleProvider, userLocaleProvider: UserLocaleProvider, @@ -44,7 +46,7 @@ internal open class BuiltinRepliesFactoryProvider internal constructor() { return BuiltinRepliesFactoryDefaultMessagesFactoryAdapter(defaultMessagesFactory) } - return DefaultBuiltinRepliesFactory(localizationService, textCommandLocaleProvider, userLocaleProvider) + return DefaultBuiltinRepliesFactory(permissionLocalization, localizationService, textCommandLocaleProvider, userLocaleProvider) } private fun hasCustomDefaultMessages(): Boolean { diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt new file mode 100644 index 000000000..a5eb7da8d --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt @@ -0,0 +1,39 @@ +package io.github.freya022.botcommands.internal.localization + +import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker +import io.github.freya022.botcommands.api.core.service.ServiceContainer +import io.github.freya022.botcommands.api.core.service.annotations.BService +import io.github.freya022.botcommands.api.core.service.annotations.ConditionalService +import io.github.freya022.botcommands.api.core.service.getInterfacedServiceTypes +import io.github.freya022.botcommands.api.core.utils.simpleNestedName +import io.github.freya022.botcommands.api.localization.DefaultPermissionLocalization +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.PermissionLocalization +import io.github.freya022.botcommands.internal.utils.classRef +import org.springframework.boot.autoconfigure.AutoConfiguration +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.context.annotation.Bean + +@AutoConfiguration +@ConditionalOnMissingBean(PermissionLocalization::class) +@BService +internal open class PermissionLocalizationProvider internal constructor() { + + @Bean + @BService + @ConditionalService(ActivationCondition::class) + open fun permissionLocalization(localizationService: LocalizationService): PermissionLocalization { + return DefaultPermissionLocalization(localizationService) + } + + internal object ActivationCondition : ConditionalServiceChecker { + override fun checkServiceAvailability(serviceContainer: ServiceContainer, checkedClass: Class<*>): String? { + val types = serviceContainer.getInterfacedServiceTypes() + if (types.isNotEmpty()) { + return "An user supplied ${classRef()} is already active (${types.first().simpleNestedName})" + } + + return null + } + } +} \ No newline at end of file From f9c15df504f85c0df9d49e40d88cf1f1f46842f3 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:23:59 +0200 Subject: [PATCH 07/21] Simplify exception when bundle name is not found It's not a feature's responsibility to list another feature's interfaces --- .../botcommands/api/core/replies/DefaultBuiltinReplies.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt index aa0a52eb5..ea94ccd0a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt @@ -29,11 +29,8 @@ open class DefaultBuiltinReplies( bundleName: String, ) : BuiltinReplies { - protected val localization: Localization = localizationService.getInstance(bundleName, locale) ?: run { - val mappingProviders = localizationService.getMappingProviders() - val mappingReaders = localizationService.getMappingReaders() - throwArgument("Could find localization files for '$bundleName', providers: $mappingProviders, readers: $mappingReaders") - } + protected val localization: Localization = localizationService.getInstance(bundleName, locale) + ?: throwArgument("Could not find localization files for '$bundleName'") override fun uncaughtException(event: GenericEvent?): MessageCreateData { return getLocalizationTemplate("uncaught_exception").localize().toMessage() From d87fd314f9c354964add3c4bafdb04b90cdf1385 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:24:48 +0200 Subject: [PATCH 08/21] Throw MissingReplyTemplateException instead of IAE when template is not found Helps disambiguate tests --- .../botcommands/api/core/replies/DefaultBuiltinReplies.kt | 3 ++- .../core/replies/exceptions/MissingReplyTemplateException.kt | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt index ea94ccd0a..5b9b81172 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt @@ -2,6 +2,7 @@ package io.github.freya022.botcommands.api.core.replies import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo +import io.github.freya022.botcommands.api.core.replies.exceptions.MissingReplyTemplateException import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService import io.github.freya022.botcommands.api.localization.LocalizationTemplate @@ -112,7 +113,7 @@ open class DefaultBuiltinReplies( protected fun getLocalizationTemplate(path: String): LocalizationTemplate { val template = localization[path] - ?: throwArgument("Template '$path' could not be found, available keys: ${localization.keys}") + ?: throw MissingReplyTemplateException("Template '$path' could not be found, available keys: ${localization.keys}") return template } diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt new file mode 100644 index 000000000..349a483e0 --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt @@ -0,0 +1,3 @@ +package io.github.freya022.botcommands.api.core.replies.exceptions + +class MissingReplyTemplateException(message: String) : IllegalArgumentException(message) \ No newline at end of file From b2ee9bf4dac4ffdcfeef24cb9307b1d8310b66c7 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:25:22 +0200 Subject: [PATCH 09/21] Return precise (but still API) types in DefaultBuiltinRepliesFactory --- .../api/core/replies/DefaultBuiltinRepliesFactory.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt index 180f5e928..1a3fe776a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt @@ -42,10 +42,10 @@ class DefaultBuiltinRepliesFactory( private val bundleName: String = "BuiltinReplies", ) : BuiltinRepliesFactory { - private val cache: MutableMap = hashMapOf() + private val cache: MutableMap = hashMapOf() private val lock = ReentrantLock() - override fun get(locale: Locale): BuiltinReplies { + override fun get(locale: Locale): DefaultBuiltinReplies { cache[locale]?.let { return it } return lock.withLock { @@ -53,7 +53,7 @@ class DefaultBuiltinRepliesFactory( } } - override fun get(event: MessageReceivedEvent): BuiltinReplies = get(textCommandLocaleProvider.getLocale(event)) + override fun get(event: MessageReceivedEvent): DefaultBuiltinReplies = get(textCommandLocaleProvider.getLocale(event)) - override fun get(event: Interaction): BuiltinReplies = get(userLocaleProvider.getLocale(event)) + override fun get(event: Interaction): DefaultBuiltinReplies = get(userLocaleProvider.getLocale(event)) } \ No newline at end of file From bc030314bda591a18e4e68f9efb2036e65462fd0 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:26:24 +0200 Subject: [PATCH 10/21] Use snake_case instead of camelCase for template variables --- .../botcommands/api/core/replies/DefaultBuiltinReplies.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt index 5b9b81172..de37e0fc8 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt @@ -76,19 +76,19 @@ open class DefaultBuiltinReplies( } override fun resolverChannelNotFound(event: GenericEvent?, channelId: Long): MessageCreateData { - return getLocalizationTemplate("resolver.channel.not_found").localize("channelId" to channelId).toMessage() + return getLocalizationTemplate("resolver.channel.not_found").localize("channel_id" to channelId).toMessage() } override fun resolverChannelMissingAccess(event: GenericEvent?, channelId: Long): MessageCreateData { - return getLocalizationTemplate("resolver.channel.missing_access").localize("channelId" to channelId).toMessage() + return getLocalizationTemplate("resolver.channel.missing_access").localize("channel_id" to channelId).toMessage() } override fun resolverUserNotFound(event: GenericEvent?, userId: Long): MessageCreateData { - return getLocalizationTemplate("resolver.user.not_found").localize("userId" to userId).toMessage() + return getLocalizationTemplate("resolver.user.not_found").localize("user_id" to userId).toMessage() } override fun slashCommandUnresolvableOption(event: GenericEvent?, option: SlashCommandOption): MessageCreateData { - return getLocalizationTemplate("commands.slash.option.unresolvable").localize("optionName" to option.discordName).toMessage() + return getLocalizationTemplate("commands.slash.option.unresolvable").localize("option_name" to option.discordName).toMessage() } override fun closedDirectMessages(event: GenericEvent?): MessageCreateData { From e263833a9f9caf09d39588b1e4b179db4670eab3 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:28:14 +0200 Subject: [PATCH 11/21] Add default built-in replies --- .../BuiltinReplies-default.json | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/resources/bc_localization/BuiltinReplies-default.json diff --git a/src/main/resources/bc_localization/BuiltinReplies-default.json b/src/main/resources/bc_localization/BuiltinReplies-default.json new file mode 100644 index 000000000..041a624ca --- /dev/null +++ b/src/main/resources/bc_localization/BuiltinReplies-default.json @@ -0,0 +1,29 @@ +{ + "uncaught_exception": "An uncaught exception occurred and has been reported to the bot developers, please try again later", + + "missing.permissions.user": "You are not allowed to do this", + "missing.permissions.bot": "I am missing these permissions: {permissions}", + "owner_only": "Only the owner can use this", + + "ratelimited.user": "You will be able to use this {timestamp}", + "ratelimited.channel": "You will be able to use this, in this channel, {timestamp}", + "ratelimited.guild": "You will be able to use this, in this guild, {timestamp}", + + "commands.application.not_available": "Application commands are not available yet, please try again later", + "commands.text.not_found": "Unknown command, maybe you meant: {suggestions}", + + "resolver.channel.not_found": "The target channel does not exist anymore", + "resolver.channel.missing_access": "The bot cannot access {channel_id}", + "resolver.user.not_found": "The target user does not exist anymore", + + "commands.slash.option.unresolvable": "The option '{option_name}' could not be resolved.", + + "direct_messages.closed": "Unable to send you a DM, please open your DMs from this server", + + "nsfw_only": "This command can only be used in NSFW channels", + + "components.not_allowed": "You are not allowed to use this", + "components.expired": "This component is not usable anymore", + + "modals.expired": "This modal is no longer available" +} \ No newline at end of file From 3a2b59a2b766121a27cb384d250ecb81b29ad6c3 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:29:49 +0200 Subject: [PATCH 12/21] Test PermissionLocalization --- .../framework/PermissionLocalizationTests.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt new file mode 100644 index 000000000..7679506eb --- /dev/null +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt @@ -0,0 +1,38 @@ +package io.github.freya022.botcommands.framework + +import io.github.freya022.botcommands.api.localization.DefaultPermissionLocalization +import io.github.freya022.botcommands.api.localization.LocalizationService +import io.mockk.every +import io.mockk.mockk +import net.dv8tion.jda.api.Permission +import java.util.* +import kotlin.test.Test +import kotlin.test.assertEquals + +class PermissionLocalizationTests { + + @Test + fun `Should use Permission's enum name when there are no bundles`() { + val localizationService = mockk { + every { getInstance(any(), any()) } returns null + } + + val permissionLocalization = DefaultPermissionLocalization(localizationService) + val actual = permissionLocalization.localize(Permission.VIEW_CHANNEL, Locale.FRENCH) + + assertEquals("View Channels", actual) + } + + @Test + fun `Should be able to use the default bundle`() { + val expected = "Localized permission name" + val localizationService = mockk { + every { getInstance("Permissions", Locale.FRENCH)?.get("VIEW_CHANNEL")?.localize() } returns expected + } + + val permissionLocalization = DefaultPermissionLocalization(localizationService) + val actual = permissionLocalization.localize(Permission.VIEW_CHANNEL, Locale.FRENCH) + + assertEquals(expected, actual) + } +} \ No newline at end of file From c691149bdb0298ba00a78e3cfe6d395b8a4a0bbc Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:29:58 +0200 Subject: [PATCH 13/21] Test BuiltinReplies --- .../framework/BuiltinRepliesTests.kt | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/test/kotlin/io/github/freya022/botcommands/framework/BuiltinRepliesTests.kt diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BuiltinRepliesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BuiltinRepliesTests.kt new file mode 100644 index 000000000..177d836fc --- /dev/null +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BuiltinRepliesTests.kt @@ -0,0 +1,139 @@ +@file:Suppress("DEPRECATION", "removal") + +package io.github.freya022.botcommands.framework + +import io.github.freya022.botcommands.api.core.BotCommands +import io.github.freya022.botcommands.api.core.config.registerServiceSupplier +import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.DefaultBuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.exceptions.MissingReplyTemplateException +import io.github.freya022.botcommands.api.core.service.getService +import io.github.freya022.botcommands.api.core.utils.joinAsList +import io.github.freya022.botcommands.api.localization.DefaultMessages +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import io.github.freya022.botcommands.framework.utils.createTest +import io.github.freya022.botcommands.internal.core.replies.BuiltinRepliesFactoryProvider +import io.mockk.every +import io.mockk.mockk +import io.mockk.slot +import io.mockk.spyk +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import net.dv8tion.jda.api.utils.messages.MessageCreateData +import java.time.Instant +import java.util.* +import kotlin.reflect.KFunction +import kotlin.test.Test +import kotlin.test.assertIsNot +import kotlin.test.fail + +class BuiltinRepliesTests { + + @Test + fun `Adapter is used when custom DefaultMessagesFactory type is used`() { + val context = BotCommands.createTest { + services { + registerServiceSupplier { + object : DefaultMessagesFactory { + override fun get(locale: Locale): DefaultMessages = throw UnsupportedOperationException() + override fun get(event: MessageReceivedEvent) = throw UnsupportedOperationException() + override fun get(event: Interaction) = throw UnsupportedOperationException() + } + } + } + } + + assertIsNot(context.getService()) + } + + @Test + fun `Adapter is used when custom DefaultMessages JSON exists`() { + val context = BotCommands.createTest { + services { + registerServiceSupplier { + mockk { + every { builtinRepliesFactory(any(), any(), any(), any(), any()) } answers { callOriginal() } + + every { this@mockk["hasCustomDefaultMessages"]() } returns true + } + } + } + } + + assertIsNot(context.getService()) + } + + @Test + fun `All built-in replies have defaults`() { + val context = BotCommands.createTest { + services { + // Override the autoconfiguration so we don't unexpectedly use a different implementation + registerServiceSupplier(additionalTypes = setOf(BuiltinRepliesFactory::class)) { context -> + DefaultBuiltinRepliesFactory( + context.getService(), + context.getService(), + context.getService(), + context.getService() + ) + } + } + } + + val templatePathSlot = slot() + val builtinReplies = spyk(context.getService().get(Locale.ROOT), recordPrivateCalls = true) { + every { this@spyk["getLocalizationTemplate"](capture(templatePathSlot)) } answers { callOriginal() } + } + + val methodCalls = mapOf( + methodCall(builtinReplies::uncaughtException) { this(mockk()) }, + methodCall(builtinReplies::missingUserPermissions) { this(mockk(), emptySet()) }, + methodCall(builtinReplies::missingBotPermissions) { this(mockk(), emptySet()) }, + methodCall(builtinReplies::ownerOnly) { this(mockk()) }, + methodCall(builtinReplies::userRateLimited) { this(mockk(), Instant.now()) }, + methodCall(builtinReplies::channelRateLimited) { this(mockk(), Instant.now()) }, + methodCall(builtinReplies::guildRateLimited) { this(mockk(), Instant.now()) }, + methodCall(builtinReplies::applicationCommandsNotAvailable) { this(mockk()) }, + methodCall(builtinReplies::commandNotFound) { this(mockk(), emptySet()) }, + methodCall(builtinReplies::resolverChannelNotFound) { this(mockk(), 0) }, + methodCall(builtinReplies::resolverChannelMissingAccess) { this(mockk(), 0) }, + methodCall(builtinReplies::resolverUserNotFound) { this(mockk(), 0) }, + methodCall(builtinReplies::slashCommandUnresolvableOption) { + this(mockk(), mockk { + every { discordName } returns "discord_name" + }) + }, + methodCall(builtinReplies::closedDirectMessages) { this(mockk()) }, + methodCall(builtinReplies::nsfwOnly) { this(mockk()) }, + methodCall(builtinReplies::componentNotAllowed) { this(mockk()) }, + methodCall(builtinReplies::componentExpired) { this(mockk()) }, + methodCall(builtinReplies::modalExpired) { this(mockk()) }, + ) + + val missingTests = BuiltinReplies::class.java.declaredMethods.mapTo(hashSetOf()) { it.name } - methodCalls.keys + if (missingTests.isNotEmpty()) { + fail("The following methods are missing tests:\n" + missingTests.joinAsList()) + } + + val methodsMissingTemplate: MutableList = arrayListOf() + methodCalls.values.forEach { methodCall -> + templatePathSlot.clear() + try { + methodCall() + } catch (_: MissingReplyTemplateException) { + methodsMissingTemplate += templatePathSlot.captured + } + } + + if (methodsMissingTemplate.isNotEmpty()) { + fail("The following template keys are missing default translations:\n" + methodsMissingTemplate.joinAsList()) + } + } + + private fun > methodCall( + callableRef: F, + executor: F.() -> Unit + ): Pair Unit> { + return callableRef.name to { executor(callableRef) } + } +} \ No newline at end of file From 06adcd792e24ac1f5d9ae5ffca8abd8d89fac089 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 16:55:16 +0200 Subject: [PATCH 14/21] Update `getMissingPermissions` docs --- .../io/github/freya022/botcommands/api/core/utils/JDA.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt index a9eb76309..92362e47f 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/utils/JDA.kt @@ -7,7 +7,7 @@ import dev.minn.jda.ktx.messages.InlineMessage import dev.minn.jda.ktx.messages.MessageCreate import dev.minn.jda.ktx.messages.MessageEdit import io.github.freya022.botcommands.api.core.exceptions.InvalidChannelTypeException -import io.github.freya022.botcommands.api.localization.DefaultMessages +import io.github.freya022.botcommands.api.localization.PermissionLocalization import io.github.freya022.botcommands.internal.utils.deferredRestAction import io.github.freya022.botcommands.internal.utils.takeIfFinite import net.dv8tion.jda.api.JDA @@ -242,9 +242,9 @@ inline fun suppressContentWarning(block: () -> R): R { /** * Computes the missing permissions from the specified permission holder, - * If you plan on showing them, be sure to use [DefaultMessages.getPermission] + * if you plan on showing them, be sure to use [PermissionLocalization.localize]. * - * @see DefaultMessages.getPermission + * @see PermissionLocalization.localize */ fun getMissingPermissions(requiredPerms: EnumSet, permissionHolder: IPermissionHolder, channel: GuildChannel): Set = EnumSet.copyOf(requiredPerms).also { it.removeAll(permissionHolder.getPermissions(channel)) } From 24ea31d656747481af6b736cdc998adf61415e70 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 17:40:09 +0200 Subject: [PATCH 15/21] Rename BuiltinReplies to BotCommandsMessages --- .../api/localization/DefaultMessages.java | 2 +- .../handler/DefaultRateLimitHandler.kt | 12 ++-- .../api/core/config/BTextConfig.kt | 4 +- ...iltinReplies.kt => BotCommandsMessages.kt} | 6 +- ...ctory.kt => BotCommandsMessagesFactory.kt} | 18 +++--- ...plies.kt => DefaultBotCommandsMessages.kt} | 10 +-- ...t => DefaultBotCommandsMessagesFactory.kt} | 30 ++++----- .../service/annotations/InterfacedService.kt | 4 +- .../localization/DefaultMessagesFactory.kt | 2 +- .../api/localization/LocalizableAction.kt | 12 ++-- .../resolvers/SlashParameterResolver.kt | 6 +- .../application/ApplicationCommandListener.kt | 16 ++--- .../application/slash/SlashCommandInfoImpl.kt | 4 +- .../ratelimit/handler/RateLimitHandler.kt | 6 +- .../internal/commands/text/HelpCommand.kt | 10 +-- .../commands/text/TextCommandsListener.kt | 16 ++--- .../controller/ComponentsListener.kt | 14 ++--- .../handler/ComponentHandlerExecutor.kt | 6 +- ...CommandsMessagesDefaultMessagesAdapter.kt} | 6 +- ...gesFactoryDefaultMessagesFactoryAdapter.kt | 27 ++++++++ ... => BotCommandsMessagesFactoryProvider.kt} | 20 +++--- ...iesFactoryDefaultMessagesFactoryAdapter.kt | 27 -------- .../LocalizableInteractionFactory.kt | 6 +- .../interaction/LocalizableInteractionImpl.kt | 12 ++-- .../text/LocalizableTextCommandFactory.kt | 6 +- .../text/LocalizableTextCommandImpl.kt | 12 ++-- .../internal/modals/ModalListener.kt | 10 +-- .../AbstractUserSnowflakeResolver.kt | 6 +- .../resolvers/ChannelResolverFactory.kt | 10 +-- ...esTests.kt => BotCommandsMessagesTests.kt} | 62 +++++++++---------- 30 files changed, 191 insertions(+), 191 deletions(-) rename src/main/kotlin/io/github/freya022/botcommands/api/core/replies/{BuiltinReplies.kt => BotCommandsMessages.kt} (97%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/replies/{BuiltinRepliesFactory.kt => BotCommandsMessagesFactory.kt} (60%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/replies/{DefaultBuiltinReplies.kt => DefaultBotCommandsMessages.kt} (96%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/replies/{DefaultBuiltinRepliesFactory.kt => DefaultBotCommandsMessagesFactory.kt} (63%) rename src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/{BuiltinRepliesDefaultMessagesAdapter.kt => BotCommandsMessagesDefaultMessagesAdapter.kt} (95%) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt rename src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/{BuiltinRepliesFactoryProvider.kt => BotCommandsMessagesFactoryProvider.kt} (79%) delete mode 100644 src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt rename src/test/kotlin/io/github/freya022/botcommands/framework/{BuiltinRepliesTests.kt => BotCommandsMessagesTests.kt} (59%) diff --git a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java index 5c547cc4d..219d96881 100644 --- a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java +++ b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java @@ -43,7 +43,7 @@ * * @see Localization * - * @deprecated This has been replaced by {@link io.github.freya022.botcommands.api.core.replies.DefaultBuiltinReplies DefaultBuiltinReplies} + * @deprecated This has been replaced by {@link io.github.freya022.botcommands.api.core.replies.DefaultBotCommandsMessages DefaultBotCommandsMessages} */ @Deprecated(since = "3.1.0-beta.1", forRemoval = true) public final class DefaultMessages { diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt index 630f6c05e..98f991491 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt @@ -7,8 +7,8 @@ import io.github.freya022.botcommands.api.commands.application.ApplicationComman import io.github.freya022.botcommands.api.commands.ratelimit.RateLimitScope import io.github.freya022.botcommands.api.commands.text.TextCommandInfo import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.awaitCatching import io.github.freya022.botcommands.api.core.utils.namedDefaultScope @@ -38,7 +38,7 @@ private val deleteScope = namedDefaultScope("Rate limit message delete", 1) * then it is sent to the user's DMs, or returns if not possible. * - Interactions are simply replying an ephemeral message to the user. * - * All messages sent to the user are localized messages from [BuiltinReplies] and will be deleted when expired. + * All messages sent to the user are localized messages from [BotCommandsMessages] and will be deleted when expired. * * **Note:** The rate limit message won't be deleted in a private channel, * or if the [refill delay][ConsumptionProbe.nanosToWaitForRefill] is longer than 10 minutes. @@ -62,7 +62,7 @@ class DefaultRateLimitHandler( event.guildChannel.canTalk() -> event.channel else -> event.author.openPrivateChannel().await() } - val messages = context.getService().get(event) + val messages = context.getService().get(event) val content = getRateLimitMessage(event, messages, probe) runIgnoringResponse(ErrorResponse.CANNOT_SEND_TO_USER) { @@ -100,7 +100,7 @@ class DefaultRateLimitHandler( probe: ConsumptionProbe ) where T : GenericInteractionCreateEvent, T : IReplyCallback { - val messages = context.getService().get(event) + val messages = context.getService().get(event) val content = getRateLimitMessage(event, messages, probe) val hook = event.reply(content).setEphemeral(true).await() // Only schedule delete if the interaction hook doesn't expire before @@ -115,7 +115,7 @@ class DefaultRateLimitHandler( private fun getRateLimitMessage( event: Event, - replies: BuiltinReplies, + replies: BotCommandsMessages, probe: ConsumptionProbe ): MessageCreateData { val deadline = Instant.now().plusNanos(probe.nanosToWaitForRefill) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt index 4ffb0f5b5..724642c65 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt @@ -4,7 +4,7 @@ import dev.freya02.jda.emojis.unicode.Emojis import io.github.freya022.botcommands.api.commands.text.IHelpCommand import io.github.freya022.botcommands.api.commands.text.TextPrefixSupplier import io.github.freya022.botcommands.api.commands.text.annotations.RequiresTextCommands -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages import io.github.freya022.botcommands.api.core.service.annotations.InjectedService import io.github.freya022.botcommands.api.core.utils.toImmutableList import io.github.freya022.botcommands.internal.core.config.ConfigDSL @@ -78,7 +78,7 @@ interface BTextConfig { /** * Emoji used to indicate a user that their DMs are closed. * - * This is only used if [the closed DMs error message][BuiltinReplies.closedDirectMessages] can't be sent. + * This is only used if [the closed DMs error message][BotCommandsMessages.closedDirectMessages] can't be sent. * * Default: `mailbox_closed` * diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt similarity index 97% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt index 6a1abd0d5..cba55f944 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt @@ -9,11 +9,11 @@ import net.dv8tion.jda.api.utils.messages.MessageCreateData import java.time.Instant /** - * Returns the messages used by the framework, instance produced by [BuiltinRepliesFactory]. + * Returns the messages used by the framework, instance produced by [BotCommandsMessagesFactory]. * - * @see BuiltinRepliesFactory + * @see BotCommandsMessagesFactory */ -interface BuiltinReplies { +interface BotCommandsMessages { /** * @return Message to display when an uncaught exception occurs diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt similarity index 60% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt index 39af6991a..b5e80293d 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt @@ -11,33 +11,33 @@ import net.dv8tion.jda.api.interactions.Interaction import java.util.* /** - * Factory of [BuiltinReplies], the default implementation is [DefaultBuiltinRepliesFactory], or, + * Factory of [BotCommandsMessages], the default implementation is [DefaultBotCommandsMessagesFactory], or, * if a non-default [DefaultMessagesFactory] exists, an adapter is used. * * ### Complete customization * - * Returning a [BuiltinRepliesFactory] from a service factory will disable the default implementation, + * Returning a [BotCommandsMessagesFactory] from a service factory will disable the default implementation, * this will let you return a completely custom instance, * in which you can craft entirely custom messages in any way you see fit. */ @InterfacedService(acceptMultiple = false) -interface BuiltinRepliesFactory { +interface BotCommandsMessagesFactory { /** - * Retrieves a [BuiltinReplies] instance for the given locale. + * Retrieves a [BotCommandsMessages] instance for the given locale. */ - fun get(locale: Locale): BuiltinReplies + fun get(locale: Locale): BotCommandsMessages /** - * Retrieves a [BuiltinReplies] instance, with the locale derived from this event. + * Retrieves a [BotCommandsMessages] instance, with the locale derived from this event. * * By default, this uses [TextCommandLocaleProvider] to get the locale. */ - fun get(event: MessageReceivedEvent): BuiltinReplies + fun get(event: MessageReceivedEvent): BotCommandsMessages /** - * Retrieves a [BuiltinReplies] instance, with the locale derived from this interaction. + * Retrieves a [BotCommandsMessages] instance, with the locale derived from this interaction. * * By default, this uses [UserLocaleProvider] to get the locale. */ - fun get(event: Interaction): BuiltinReplies + fun get(event: Interaction): BotCommandsMessages } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt similarity index 96% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt index de37e0fc8..715295314 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinReplies.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt @@ -18,17 +18,17 @@ import java.util.* import kotlin.to /** - * Default implementation of [BuiltinReplies], - * see [DefaultBuiltinRepliesFactory] for more details. + * Default implementation of [BotCommandsMessages], + * see [DefaultBotCommandsMessagesFactory] for more details. * - * @see DefaultBuiltinRepliesFactory + * @see DefaultBotCommandsMessagesFactory */ -open class DefaultBuiltinReplies( +open class DefaultBotCommandsMessages( protected val permissionLocalization: PermissionLocalization, localizationService: LocalizationService, protected val locale: Locale, bundleName: String, -) : BuiltinReplies { +) : BotCommandsMessages { protected val localization: Localization = localizationService.getInstance(bundleName, locale) ?: throwArgument("Could not find localization files for '$bundleName'") diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt similarity index 63% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt index 1a3fe776a..47df55ebe 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBuiltinRepliesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt @@ -12,48 +12,48 @@ import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock /** - * Default implementation of [BuiltinRepliesFactory]. + * Default implementation of [BotCommandsMessagesFactory]. * - * Instances returned by this factory are [DefaultBuiltinReplies], + * Instances returned by this factory are [DefaultBotCommandsMessages], * which uses [LocalizationService] to get a localization bundle using the provided [bundleName]. * - * By default, an instance of this factory is registered using the default bundle name (`BuiltinReplies`), + * By default, an instance of this factory is registered using the default bundle name (`BotCommandsMessages`), * you can override the default factory by providing a corresponding service factory. * * ### Light customization / Supporting more locales * - * With the default values, the localization templates would be loaded from `/bc_localization/BuiltinReplies-default.json`, - * you may change the values by creating a new `BuiltinReplies.json`, + * With the default values, the localization templates would be loaded from `/bc_localization/BotCommandsMessages-default.json`, + * you may change the values by creating a new `BotCommandsMessages.json`, * you can also support more locales following by appending an underscore and the [language tag][Locale.toLanguageTag], - * such as `BuiltinReplies_fr.json`. + * such as `BotCommandsMessages_fr.json`. * - * The localization paths must be identical to those used by [DefaultBuiltinReplies], + * The localization paths must be identical to those used by [DefaultBotCommandsMessages], * but the placeholders can be modified but must keep the same names, they can also be removed. * * Refer to [Localization] for mode customization details. * * @see Localization */ -class DefaultBuiltinRepliesFactory( +class DefaultBotCommandsMessagesFactory( private val permissionLocalization: PermissionLocalization, private val localizationService: LocalizationService, private val textCommandLocaleProvider: TextCommandLocaleProvider, private val userLocaleProvider: UserLocaleProvider, - private val bundleName: String = "BuiltinReplies", -) : BuiltinRepliesFactory { + private val bundleName: String = "BotCommandsMessages", +) : BotCommandsMessagesFactory { - private val cache: MutableMap = hashMapOf() + private val cache: MutableMap = hashMapOf() private val lock = ReentrantLock() - override fun get(locale: Locale): DefaultBuiltinReplies { + override fun get(locale: Locale): DefaultBotCommandsMessages { cache[locale]?.let { return it } return lock.withLock { - cache.getOrPut(locale) { DefaultBuiltinReplies(permissionLocalization, localizationService, locale, bundleName) } + cache.getOrPut(locale) { DefaultBotCommandsMessages(permissionLocalization, localizationService, locale, bundleName) } } } - override fun get(event: MessageReceivedEvent): DefaultBuiltinReplies = get(textCommandLocaleProvider.getLocale(event)) + override fun get(event: MessageReceivedEvent): DefaultBotCommandsMessages = get(textCommandLocaleProvider.getLocale(event)) - override fun get(event: Interaction): DefaultBuiltinReplies = get(userLocaleProvider.getLocale(event)) + override fun get(event: Interaction): DefaultBotCommandsMessages = get(userLocaleProvider.getLocale(event)) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt index 6c2e3897f..45dc190db 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt @@ -14,7 +14,7 @@ import io.github.freya022.botcommands.api.components.ComponentInteractionFilter import io.github.freya022.botcommands.api.core.* import io.github.freya022.botcommands.api.core.db.ConnectionSupplier import io.github.freya022.botcommands.api.core.db.query.ParametrizedQueryFactory -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.localization.arguments.factories.FormattableArgumentFactory import io.github.freya022.botcommands.api.localization.providers.LocalizationMapProvider @@ -37,7 +37,7 @@ import io.github.freya022.botcommands.api.localization.readers.LocalizationMapRe * @see ICoroutineEventManagerSupplier * @see JDAService * - * @see BuiltinRepliesFactory + * @see BotCommandsMessagesFactory * * @see GlobalExceptionHandler * diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt index ffed5faae..0a52848b2 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/DefaultMessagesFactory.kt @@ -17,7 +17,7 @@ import java.util.* * * @see InterfacedService @InterfacedService */ -@Deprecated("Replaced by BuiltinRepliesFactory") +@Deprecated("Replaced by BotCommandsMessagesFactory") @InterfacedService(acceptMultiple = false) interface DefaultMessagesFactory { /** diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt index e847c04e7..1d2e978b6 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt @@ -1,8 +1,8 @@ package io.github.freya022.botcommands.api.localization import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.context.LocalizationContext import io.github.freya022.botcommands.api.localization.context.PairEntry import io.github.freya022.botcommands.api.localization.context.mapToEntries @@ -46,15 +46,15 @@ interface LocalizableAction { * @see DefaultMessagesFactory */ @Suppress("DEPRECATION", "removal") - @Deprecated("Replaced with getBuiltinReplies()") + @Deprecated("Replaced with getBotCommandsMessages()") fun getDefaultMessages(): DefaultMessages /** - * Retrieves a [BuiltinReplies] instance, using a locale suitable for messages sent to the user. + * Retrieves a [BotCommandsMessages] instance, using a locale suitable for messages sent to the user. * - * @see BuiltinRepliesFactory + * @see BotCommandsMessagesFactory */ - fun getBuiltinReplies(): BuiltinReplies + fun getBotCommandsMessages(): BotCommandsMessages /** * Returns the localized message at the following [path][localizationPath], diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt index 5098383a5..5b84a3f34 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt @@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.commands.application.slash.annotations import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.annotations.AutocompleteHandler import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.application.slash.options.builder.SlashCommandOptionBuilder -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages import io.github.freya022.botcommands.api.parameters.ParameterResolver import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent @@ -57,7 +57,7 @@ interface SlashParameterResolver : IParameterResolver * and you should reply if this is a [SlashCommandInteractionEvent]. * * If the interaction is not replied to, - * the handler sends an [unresolvable option error message][BuiltinReplies.slashCommandUnresolvableOption]. + * the handler sends an [unresolvable option error message][BotCommandsMessages.slashCommandUnresolvableOption]. * * @param option The option currently being resolved * @param event The corresponding event, could be a [SlashCommandInteractionEvent] or a [CommandAutoCompleteInteractionEvent] @@ -74,7 +74,7 @@ interface SlashParameterResolver : IParameterResolver * and you should reply if this is a [SlashCommandInteractionEvent]. * * If the interaction is not replied to, - * the handler sends an [unresolvable option error message][BuiltinReplies.slashCommandUnresolvableOption]. + * the handler sends an [unresolvable option error message][BotCommandsMessages.slashCommandUnresolvableOption]. * * @param option The option currently being resolved * @param event The corresponding event, could be a [SlashCommandInteractionEvent] or a [CommandAutoCompleteInteractionEvent] diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt index 7ff227577..e15421c9e 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt @@ -15,8 +15,8 @@ import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.entities.inputUser -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.getMissingPermissions @@ -50,7 +50,7 @@ private val logger = KotlinLogging.logger { } internal class ApplicationCommandListener internal constructor( private val context: BContext, private val applicationCommandsBuilder: ApplicationCommandsBuilder, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val rateLimitHandler: RateLimitHandler, filters: List, @@ -146,7 +146,7 @@ internal class ApplicationCommandListener internal constructor( } else { logger.debug { "Ignored '${event.fullCommandName}' as guild (${guild!!.id}) commands could not be updated" } } - return event.reply(builtinRepliesFactory.get(event).applicationCommandsNotAvailable(event)).setEphemeral(true).queue() + return event.reply(messagesFactory.get(event).applicationCommandsNotAvailable(event)).setEphemeral(true).queue() } //This is done so warnings are printed after the exception @@ -227,9 +227,9 @@ internal class ApplicationCommandListener internal constructor( exceptionHandler.handleException(event, e, "application command '${event.commandString}'", emptyMap(), logLevel) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) + event.replyExceptionMessage(messagesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) + event.replyExceptionMessage(messagesFactory.get(event).uncaughtException(event)) } } @@ -280,7 +280,7 @@ internal class ApplicationCommandListener internal constructor( } } - private inline fun fromReplies(event: Interaction, crossinline block: BuiltinReplies.() -> MessageCreateData): MessageCreateData { - return builtinRepliesFactory.get(event).run(block) + private inline fun fromReplies(event: Interaction, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { + return messagesFactory.get(event).run(block) } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt index 815c4c15a..dc5308386 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt @@ -5,7 +5,7 @@ import io.github.freya022.botcommands.api.commands.application.slash.GlobalSlash import io.github.freya022.botcommands.api.commands.application.slash.GuildSlashEvent import io.github.freya022.botcommands.api.commands.application.slash.SlashCommandInfo import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.* @@ -155,7 +155,7 @@ private fun onUnresolvableOption( else -> { //Only use the generic message if the user didn't handle this situation if (!event.isAcknowledged && event is SlashCommandInteractionEvent) { - val defaultMessages = option.context.getService().get(event) + val defaultMessages = option.context.getService().get(event) event.reply(defaultMessages.slashCommandUnresolvableOption(event, option)) .setEphemeral(true) .queue() diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt index d1b47fa57..e1ec84ef1 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt @@ -5,7 +5,7 @@ import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimi import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.BotOwners import io.github.freya022.botcommands.api.core.config.BConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.loggerOf import io.github.freya022.botcommands.internal.commands.application.ApplicationCommandInfoImpl @@ -27,7 +27,7 @@ internal class RateLimitHandler internal constructor( private val context: BContext, private val botOwners: BotOwners, private val rateLimitContainer: RateLimitContainer, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, config: BConfig, ) { private val enableOwnerBypass = config.enableOwnerBypass @@ -90,7 +90,7 @@ internal class RateLimitHandler internal constructor( val rateLimitInfo = rateLimitContainer[group] ?: run { componentsListenerLogger.warn { "Could not find a rate limiter named '$group'" } - event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() + event.reply(messagesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() return } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt index 92c3d96b3..fbbe92826 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt @@ -7,7 +7,7 @@ import io.github.freya022.botcommands.api.commands.text.annotations.RequiresText import io.github.freya022.botcommands.api.commands.text.provider.TextCommandManager import io.github.freya022.botcommands.api.commands.text.provider.TextCommandProvider import io.github.freya022.botcommands.api.core.config.BTextConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -44,14 +44,14 @@ internal open class BuiltInHelpCommandProvider { @ConditionalOnMissingBean(IHelpCommand::class) internal open fun builtInHelpCommand( context: BContextImpl, - builtinRepliesFactory: BuiltinRepliesFactory, + messagesFactory: BotCommandsMessagesFactory, textCommandsContext: TextCommandsContext, helpBuilderConsumer: HelpBuilderConsumer?, - ) = HelpCommand(context, builtinRepliesFactory, textCommandsContext, helpBuilderConsumer) + ) = HelpCommand(context, messagesFactory, textCommandsContext, helpBuilderConsumer) } internal class HelpCommand internal constructor( private val context: BContextImpl, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val textCommandsContext: TextCommandsContext, private val helpBuilderConsumer: HelpBuilderConsumer? ) : IHelpCommand, TextCommandProvider { @@ -118,7 +118,7 @@ internal class HelpCommand internal constructor( // Ignore and reply in channel/react if we can't send to DMs .handle(ErrorResponse.CANNOT_SEND_TO_USER) { if (event.channel.canTalk()) - event.channel.sendMessage(builtinRepliesFactory.get(event).closedDirectMessages(event)).await() + event.channel.sendMessage(messagesFactory.get(event).closedDirectMessages(event)).await() else if (hasReactionPermissions) // May throw REACTION_BLOCKED event.message.addReaction(context.textConfig.dmClosedEmoji).await() diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt index 82fabd381..7a52536c6 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt @@ -10,8 +10,8 @@ import io.github.freya022.botcommands.api.core.JDAService import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BTextConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -44,7 +44,7 @@ private val spacePattern = Regex("\\s+") @ConditionalService(TextCommandsListener.ActivationCondition::class) internal class TextCommandsListener internal constructor( private val context: BContext, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val textCommandsContext: TextCommandsContextImpl, private val localizableTextCommandFactory: LocalizableTextCommandFactory, private val rateLimitHandler: RateLimitHandler, @@ -134,9 +134,9 @@ internal class TextCommandsListener internal constructor( private suspend fun handleException(event: MessageReceivedEvent, e: Throwable, msg: String) { exceptionHandler.handleException(event, e, "text command '$msg'", mapOf("Message" to event.jumpUrl)) if (e is InsufficientPermissionException) { - replyError(event, builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) + replyError(event, messagesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - replyError(event, builtinRepliesFactory.get(event).uncaughtException(event)) + replyError(event, messagesFactory.get(event).uncaughtException(event)) } } @@ -245,12 +245,12 @@ internal class TextCommandsListener internal constructor( val suggestions = suggestionSupplier.getSuggestions(commandName, candidates) if (suggestions.isNotEmpty()) { - replyError(event, builtinRepliesFactory.get(event).commandNotFound(event, suggestions)) + replyError(event, messagesFactory.get(event).commandNotFound(event, suggestions)) } } - private inline fun fromReplies(event: MessageReceivedEvent, crossinline block: BuiltinReplies.() -> MessageCreateData): MessageCreateData { - return builtinRepliesFactory.get(event).run(block) + private inline fun fromReplies(event: MessageReceivedEvent, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { + return messagesFactory.get(event).run(block) } internal enum class Status { diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt index 246ab3c39..88656a258 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt @@ -12,7 +12,7 @@ import io.github.freya022.botcommands.api.core.Filter import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BComponentsConfigBuilder -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.commands.ratelimit.handler.RateLimitHandler @@ -35,7 +35,7 @@ private val logger = KotlinLogging.logger { } @RequiresComponents internal class ComponentsListener( private val context: BContext, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val rateLimitHandler: RateLimitHandler, filters: List, @@ -60,13 +60,13 @@ internal class ComponentsListener( ComponentController.parseComponentId(id) } val component = componentController.getActiveComponent(componentId) - ?: return@launch event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() + ?: return@launch event.reply(messagesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() if (component !is ActionComponentData) throwInternal("Somehow retrieved a non-executable component on a component interaction: $component") if (component.filters === ComponentFilters.INVALID_FILTERS) { - return@launch event.reply(builtinRepliesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() + return@launch event.reply(messagesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() } component.filters.onEach { filter -> @@ -100,7 +100,7 @@ internal class ComponentsListener( component: ActionComponentData ): Boolean { if (!component.constraints.isAllowed(event)) { - event.reply(builtinRepliesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() + event.reply(messagesFactory.get(event).componentNotAllowed(event)).setEphemeral(true).queue() return false } @@ -138,9 +138,9 @@ internal class ComponentsListener( "Component" to event.component )) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) + event.replyExceptionMessage(messagesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) + event.replyExceptionMessage(messagesFactory.get(event).uncaughtException(event)) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt index efcd36309..42093346f 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt @@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.components.annotations.RequiresCompone import io.github.freya022.botcommands.api.components.event.EntitySelectEvent import io.github.freya022.botcommands.api.components.event.StringSelectEvent import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.components.ComponentType @@ -32,7 +32,7 @@ private val logger = KotlinLogging.logger { } @BService @RequiresComponents internal class ComponentHandlerExecutor internal constructor( - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val componentHandlerContainer: ComponentHandlerContainer, ) { internal suspend fun runHandler(component: ActionComponentData, event: GenericComponentInteractionCreateEvent): Boolean { @@ -60,7 +60,7 @@ internal class ComponentHandlerExecutor internal constructor( Component raw data: $userData """.trimIndent() } - event.reply(builtinRepliesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() + event.reply(messagesFactory.get(event).componentExpired(event)).setEphemeral(true).queue() return false } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt similarity index 95% rename from src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt rename to src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt index acfdcb639..6f280b3aa 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesDefaultMessagesAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt @@ -4,7 +4,7 @@ package io.github.freya022.botcommands.internal.core.replies import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages import io.github.freya022.botcommands.api.localization.DefaultMessages import net.dv8tion.jda.api.Permission import net.dv8tion.jda.api.events.GenericEvent @@ -12,9 +12,9 @@ import net.dv8tion.jda.api.utils.TimeFormat import net.dv8tion.jda.api.utils.messages.MessageCreateData import java.time.Instant -internal class BuiltinRepliesDefaultMessagesAdapter internal constructor( +internal class BotCommandsMessagesDefaultMessagesAdapter internal constructor( private val defaultMessages: DefaultMessages, -) : BuiltinReplies { +) : BotCommandsMessages { override fun uncaughtException(event: GenericEvent?): MessageCreateData { return defaultMessages.generalErrorMsg.toMessage() diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt new file mode 100644 index 000000000..4a3a93e2e --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt @@ -0,0 +1,27 @@ +@file:Suppress("removal", "DEPRECATION") + +package io.github.freya022.botcommands.internal.core.replies + +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.interactions.Interaction +import java.util.* + +internal class BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter internal constructor( + private val defaultMessagesFactory: DefaultMessagesFactory, +) : BotCommandsMessagesFactory { + + override fun get(locale: Locale): BotCommandsMessages { + return BotCommandsMessagesDefaultMessagesAdapter(defaultMessagesFactory.get(locale)) + } + + override fun get(event: MessageReceivedEvent): BotCommandsMessages { + return BotCommandsMessagesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) + } + + override fun get(event: Interaction): BotCommandsMessages { + return BotCommandsMessagesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt similarity index 79% rename from src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt rename to src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt index 3f58996dc..4a678a684 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.core.replies import io.github.classgraph.ClassGraph -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory -import io.github.freya022.botcommands.api.core.replies.DefaultBuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.replies.DefaultBotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService @@ -26,27 +26,27 @@ import org.springframework.context.annotation.Bean private val logger = KotlinLogging.logger { } @AutoConfiguration -@ConditionalOnMissingBean(BuiltinRepliesFactory::class) +@ConditionalOnMissingBean(BotCommandsMessagesFactory::class) @BService -internal open class BuiltinRepliesFactoryProvider internal constructor() { +internal open class BotCommandsMessagesFactoryProvider internal constructor() { @Bean @BService @ConditionalService(ActivationCondition::class) - open fun builtinRepliesFactory( + open fun botCommandsMessagesFactory( defaultMessagesFactory: DefaultMessagesFactory, permissionLocalization: PermissionLocalization, localizationService: LocalizationService, textCommandLocaleProvider: TextCommandLocaleProvider, userLocaleProvider: UserLocaleProvider, - ): BuiltinRepliesFactory { + ): BotCommandsMessagesFactory { // Check if the user has a custom factory or if the fallback factory has customized files if (defaultMessagesFactory !is FallbackDefaultMessagesFactory || hasCustomDefaultMessages()) { logger.warn { "${classRef()} has been deprecated and will be removed in the full release." } - return BuiltinRepliesFactoryDefaultMessagesFactoryAdapter(defaultMessagesFactory) + return BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter(defaultMessagesFactory) } - return DefaultBuiltinRepliesFactory(permissionLocalization, localizationService, textCommandLocaleProvider, userLocaleProvider) + return DefaultBotCommandsMessagesFactory(permissionLocalization, localizationService, textCommandLocaleProvider, userLocaleProvider) } private fun hasCustomDefaultMessages(): Boolean { @@ -65,9 +65,9 @@ internal open class BuiltinRepliesFactoryProvider internal constructor() { internal object ActivationCondition : ConditionalServiceChecker { override fun checkServiceAvailability(serviceContainer: ServiceContainer, checkedClass: Class<*>): String? { - val types = serviceContainer.getInterfacedServiceTypes() + val types = serviceContainer.getInterfacedServiceTypes() if (types.isNotEmpty()) { - return "An user supplied ${classRef()} is already active (${types.first().simpleNestedName})" + return "An user supplied ${classRef()} is already active (${types.first().simpleNestedName})" } return null diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt deleted file mode 100644 index 44dd5c032..000000000 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BuiltinRepliesFactoryDefaultMessagesFactoryAdapter.kt +++ /dev/null @@ -1,27 +0,0 @@ -@file:Suppress("removal", "DEPRECATION") - -package io.github.freya022.botcommands.internal.core.replies - -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory -import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory -import net.dv8tion.jda.api.events.message.MessageReceivedEvent -import net.dv8tion.jda.api.interactions.Interaction -import java.util.* - -internal class BuiltinRepliesFactoryDefaultMessagesFactoryAdapter internal constructor( - private val defaultMessagesFactory: DefaultMessagesFactory, -) : BuiltinRepliesFactory { - - override fun get(locale: Locale): BuiltinReplies { - return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(locale)) - } - - override fun get(event: MessageReceivedEvent): BuiltinReplies { - return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) - } - - override fun get(event: Interaction): BuiltinReplies { - return BuiltinRepliesDefaultMessagesAdapter(defaultMessagesFactory.get(event)) - } -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt index 3b823dc6a..21db71584 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt @@ -3,7 +3,7 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService @@ -19,8 +19,8 @@ internal class LocalizableInteractionFactory internal constructor( private val userLocaleProvider: UserLocaleProvider, private val guildLocaleProvider: GuildLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, ) { internal fun create(event: IReplyCallback) = - LocalizableInteractionImpl(event, localizationService, localizationConfig, userLocaleProvider, guildLocaleProvider, defaultMessagesFactory, builtinRepliesFactory) + LocalizableInteractionImpl(event, localizationService, localizationConfig, userLocaleProvider, guildLocaleProvider, defaultMessagesFactory, messagesFactory) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt index 9abc5efbe..d86561a6a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization @@ -26,7 +26,7 @@ internal class LocalizableInteractionImpl internal constructor( private val userLocaleProvider: UserLocaleProvider, private val guildLocaleProvider: GuildLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, ) : AbstractLocalizableAction(localizationConfig, localizationService), LocalizableInteraction { @@ -44,13 +44,13 @@ internal class LocalizableInteractionImpl internal constructor( } @Suppress("DEPRECATION", "removal") - @Deprecated("Replaced with getBuiltinReplies()") + @Deprecated("Replaced with getBotCommandsMessages()") override fun getDefaultMessages(): DefaultMessages { return defaultMessagesFactory.get(deferrableCallback) } - override fun getBuiltinReplies(): BuiltinReplies { - return builtinRepliesFactory.get(deferrableCallback) + override fun getBotCommandsMessages(): BotCommandsMessages { + return messagesFactory.get(deferrableCallback) } override fun getUserMessage(localizationPath: String, vararg entries: Localization.Entry): String { diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt index 26aa8ab9a..bf3862a52 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt @@ -3,7 +3,7 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService @@ -17,8 +17,8 @@ internal class LocalizableTextCommandFactory internal constructor( private val localizationConfig: BLocalizationConfig, private val localeProvider: TextCommandLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, ) { internal fun create(event: MessageReceivedEvent) = - LocalizableTextCommandImpl(event, localizationService, localizationConfig, localeProvider, defaultMessagesFactory, builtinRepliesFactory) + LocalizableTextCommandImpl(event, localizationService, localizationConfig, localeProvider, defaultMessagesFactory, messagesFactory) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt index 376c9fab0..7efd5cd0c 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinReplies -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization @@ -24,7 +24,7 @@ internal class LocalizableTextCommandImpl internal constructor( localizationConfig: BLocalizationConfig, private val localeProvider: TextCommandLocaleProvider, private val defaultMessagesFactory: DefaultMessagesFactory, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, ) : AbstractLocalizableAction(localizationConfig, localizationService), LocalizableTextCommand { private val locale: Locale by lazy { localeProvider.getLocale(event) } @@ -38,13 +38,13 @@ internal class LocalizableTextCommandImpl internal constructor( } @Suppress("DEPRECATION", "removal") - @Deprecated("Replaced with getBuiltinReplies()") + @Deprecated("Replaced with getBotCommandsMessages()") override fun getDefaultMessages(): DefaultMessages { return defaultMessagesFactory.get(locale) } - override fun getBuiltinReplies(): BuiltinReplies { - return builtinRepliesFactory.get(locale) + override fun getBotCommandsMessages(): BotCommandsMessages { + return messagesFactory.get(locale) } override fun getGuildMessage(localizationPath: String, vararg entries: Localization.Entry): String { diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt index a318d2579..b9bb12e0b 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt @@ -2,7 +2,7 @@ package io.github.freya022.botcommands.internal.modals import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.config.BModalsConfig -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.modals.ModalEvent import io.github.freya022.botcommands.api.modals.Modals @@ -23,7 +23,7 @@ private val logger = KotlinLogging.logger { } @RequiresModals internal class ModalListener( private val context: BContextImpl, - private val builtinRepliesFactory: BuiltinRepliesFactory, + private val messagesFactory: BotCommandsMessagesFactory, private val localizableInteractionFactory: LocalizableInteractionFactory, private val modalHandlerContainer: ModalHandlerContainer, private val modalMaps: ModalMaps, @@ -43,7 +43,7 @@ internal class ModalListener( val modalData = modalMaps.consumeModal(ModalMaps.parseModalId(jdaEvent.modalId)) if (modalData == null) { //Probably the modal expired - jdaEvent.reply(builtinRepliesFactory.get(jdaEvent).modalExpired(jdaEvent)).setEphemeral(true).queue() + jdaEvent.reply(messagesFactory.get(jdaEvent).modalExpired(jdaEvent)).setEphemeral(true).queue() return@launch } @@ -72,9 +72,9 @@ internal class ModalListener( put("Modal values", event.values.associate { it.id to it.asString }) }) if (e is InsufficientPermissionException) { - event.replyExceptionMessage(builtinRepliesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) + event.replyExceptionMessage(messagesFactory.get(event).missingBotPermissions(event, setOf(e.permission))) } else { - event.replyExceptionMessage(builtinRepliesFactory.get(event).uncaughtException(event)) + event.replyExceptionMessage(messagesFactory.get(event).uncaughtException(event)) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt index 8a3d58584..767f18764 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt @@ -7,7 +7,7 @@ import io.github.freya022.botcommands.api.commands.text.options.TextCommandOptio import io.github.freya022.botcommands.api.components.options.ComponentOption import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BuiltinRepliesFactory +import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.traceNull import io.github.freya022.botcommands.api.core.utils.retrieveMemberByIdOrNull @@ -41,7 +41,7 @@ internal sealed class AbstractUserSnowflakeResolver, UserContextParameterResolver { - private val builtinRepliesFactory: BuiltinRepliesFactory = context.getService() + private val messagesFactory: BotCommandsMessagesFactory = context.getService() final override val pattern: Pattern get() = userMentionPattern final override val testExample: String = "<@1234>" @@ -75,7 +75,7 @@ internal sealed class AbstractUserSnowflakeResolver(context.getService()) + assertIsNot(context.getService()) } @Test fun `Adapter is used when custom DefaultMessages JSON exists`() { val context = BotCommands.createTest { services { - registerServiceSupplier { + registerServiceSupplier { mockk { - every { builtinRepliesFactory(any(), any(), any(), any(), any()) } answers { callOriginal() } + every { botCommandsMessagesFactory(any(), any(), any(), any(), any()) } answers { callOriginal() } every { this@mockk["hasCustomDefaultMessages"]() } returns true } @@ -61,7 +61,7 @@ class BuiltinRepliesTests { } } - assertIsNot(context.getService()) + assertIsNot(context.getService()) } @Test @@ -69,8 +69,8 @@ class BuiltinRepliesTests { val context = BotCommands.createTest { services { // Override the autoconfiguration so we don't unexpectedly use a different implementation - registerServiceSupplier(additionalTypes = setOf(BuiltinRepliesFactory::class)) { context -> - DefaultBuiltinRepliesFactory( + registerServiceSupplier(additionalTypes = setOf(BotCommandsMessagesFactory::class)) { context -> + DefaultBotCommandsMessagesFactory( context.getService(), context.getService(), context.getService(), @@ -81,36 +81,36 @@ class BuiltinRepliesTests { } val templatePathSlot = slot() - val builtinReplies = spyk(context.getService().get(Locale.ROOT), recordPrivateCalls = true) { + val messages = spyk(context.getService().get(Locale.ROOT), recordPrivateCalls = true) { every { this@spyk["getLocalizationTemplate"](capture(templatePathSlot)) } answers { callOriginal() } } val methodCalls = mapOf( - methodCall(builtinReplies::uncaughtException) { this(mockk()) }, - methodCall(builtinReplies::missingUserPermissions) { this(mockk(), emptySet()) }, - methodCall(builtinReplies::missingBotPermissions) { this(mockk(), emptySet()) }, - methodCall(builtinReplies::ownerOnly) { this(mockk()) }, - methodCall(builtinReplies::userRateLimited) { this(mockk(), Instant.now()) }, - methodCall(builtinReplies::channelRateLimited) { this(mockk(), Instant.now()) }, - methodCall(builtinReplies::guildRateLimited) { this(mockk(), Instant.now()) }, - methodCall(builtinReplies::applicationCommandsNotAvailable) { this(mockk()) }, - methodCall(builtinReplies::commandNotFound) { this(mockk(), emptySet()) }, - methodCall(builtinReplies::resolverChannelNotFound) { this(mockk(), 0) }, - methodCall(builtinReplies::resolverChannelMissingAccess) { this(mockk(), 0) }, - methodCall(builtinReplies::resolverUserNotFound) { this(mockk(), 0) }, - methodCall(builtinReplies::slashCommandUnresolvableOption) { + methodCall(messages::uncaughtException) { this(mockk()) }, + methodCall(messages::missingUserPermissions) { this(mockk(), emptySet()) }, + methodCall(messages::missingBotPermissions) { this(mockk(), emptySet()) }, + methodCall(messages::ownerOnly) { this(mockk()) }, + methodCall(messages::userRateLimited) { this(mockk(), Instant.now()) }, + methodCall(messages::channelRateLimited) { this(mockk(), Instant.now()) }, + methodCall(messages::guildRateLimited) { this(mockk(), Instant.now()) }, + methodCall(messages::applicationCommandsNotAvailable) { this(mockk()) }, + methodCall(messages::commandNotFound) { this(mockk(), emptySet()) }, + methodCall(messages::resolverChannelNotFound) { this(mockk(), 0) }, + methodCall(messages::resolverChannelMissingAccess) { this(mockk(), 0) }, + methodCall(messages::resolverUserNotFound) { this(mockk(), 0) }, + methodCall(messages::slashCommandUnresolvableOption) { this(mockk(), mockk { every { discordName } returns "discord_name" }) }, - methodCall(builtinReplies::closedDirectMessages) { this(mockk()) }, - methodCall(builtinReplies::nsfwOnly) { this(mockk()) }, - methodCall(builtinReplies::componentNotAllowed) { this(mockk()) }, - methodCall(builtinReplies::componentExpired) { this(mockk()) }, - methodCall(builtinReplies::modalExpired) { this(mockk()) }, + methodCall(messages::closedDirectMessages) { this(mockk()) }, + methodCall(messages::nsfwOnly) { this(mockk()) }, + methodCall(messages::componentNotAllowed) { this(mockk()) }, + methodCall(messages::componentExpired) { this(mockk()) }, + methodCall(messages::modalExpired) { this(mockk()) }, ) - val missingTests = BuiltinReplies::class.java.declaredMethods.mapTo(hashSetOf()) { it.name } - methodCalls.keys + val missingTests = BotCommandsMessages::class.java.declaredMethods.mapTo(hashSetOf()) { it.name } - methodCalls.keys if (missingTests.isNotEmpty()) { fail("The following methods are missing tests:\n" + missingTests.joinAsList()) } From 6fd4f64e691a945c4ca849909b99748356e088f0 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 17:43:04 +0200 Subject: [PATCH 16/21] Change package to `messages` --- .../botcommands/api/localization/DefaultMessages.java | 2 +- .../commands/ratelimit/handler/DefaultRateLimitHandler.kt | 4 ++-- .../freya022/botcommands/api/core/config/BTextConfig.kt | 2 +- .../api/core/{replies => messages}/BotCommandsMessages.kt | 2 +- .../{replies => messages}/BotCommandsMessagesFactory.kt | 2 +- .../{replies => messages}/DefaultBotCommandsMessages.kt | 4 ++-- .../DefaultBotCommandsMessagesFactory.kt | 2 +- .../exceptions/MissingReplyTemplateException.kt | 2 +- .../api/core/service/annotations/InterfacedService.kt | 2 +- .../botcommands/api/localization/LocalizableAction.kt | 4 ++-- .../api/parameters/resolvers/SlashParameterResolver.kt | 2 +- .../commands/application/ApplicationCommandListener.kt | 4 ++-- .../commands/application/slash/SlashCommandInfoImpl.kt | 2 +- .../commands/ratelimit/handler/RateLimitHandler.kt | 2 +- .../botcommands/internal/commands/text/HelpCommand.kt | 2 +- .../internal/commands/text/TextCommandsListener.kt | 4 ++-- .../internal/components/controller/ComponentsListener.kt | 2 +- .../components/handler/ComponentHandlerExecutor.kt | 2 +- .../replies/BotCommandsMessagesDefaultMessagesAdapter.kt | 2 +- ...ommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt | 4 ++-- .../core/replies/BotCommandsMessagesFactoryProvider.kt | 4 ++-- .../interaction/LocalizableInteractionFactory.kt | 2 +- .../interaction/LocalizableInteractionImpl.kt | 4 ++-- .../localization/text/LocalizableTextCommandFactory.kt | 2 +- .../localization/text/LocalizableTextCommandImpl.kt | 4 ++-- .../freya022/botcommands/internal/modals/ModalListener.kt | 2 +- .../parameters/resolvers/AbstractUserSnowflakeResolver.kt | 2 +- .../parameters/resolvers/ChannelResolverFactory.kt | 2 +- .../botcommands/framework/BotCommandsMessagesTests.kt | 8 ++++---- 29 files changed, 41 insertions(+), 41 deletions(-) rename src/main/kotlin/io/github/freya022/botcommands/api/core/{replies => messages}/BotCommandsMessages.kt (98%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/{replies => messages}/BotCommandsMessagesFactory.kt (96%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/{replies => messages}/DefaultBotCommandsMessages.kt (97%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/{replies => messages}/DefaultBotCommandsMessagesFactory.kt (97%) rename src/main/kotlin/io/github/freya022/botcommands/api/core/{replies => messages}/exceptions/MissingReplyTemplateException.kt (56%) diff --git a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java index 219d96881..ea7724c61 100644 --- a/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java +++ b/src/main/java/io/github/freya022/botcommands/api/localization/DefaultMessages.java @@ -43,7 +43,7 @@ * * @see Localization * - * @deprecated This has been replaced by {@link io.github.freya022.botcommands.api.core.replies.DefaultBotCommandsMessages DefaultBotCommandsMessages} + * @deprecated This has been replaced by {@link io.github.freya022.botcommands.api.core.messages.DefaultBotCommandsMessages DefaultBotCommandsMessages} */ @Deprecated(since = "3.1.0-beta.1", forRemoval = true) public final class DefaultMessages { diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt index 98f991491..378425aa0 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt @@ -7,8 +7,8 @@ import io.github.freya022.botcommands.api.commands.application.ApplicationComman import io.github.freya022.botcommands.api.commands.ratelimit.RateLimitScope import io.github.freya022.botcommands.api.commands.text.TextCommandInfo import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.awaitCatching import io.github.freya022.botcommands.api.core.utils.namedDefaultScope diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt index 724642c65..8253734b0 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BTextConfig.kt @@ -4,7 +4,7 @@ import dev.freya02.jda.emojis.unicode.Emojis import io.github.freya022.botcommands.api.commands.text.IHelpCommand import io.github.freya022.botcommands.api.commands.text.TextPrefixSupplier import io.github.freya022.botcommands.api.commands.text.annotations.RequiresTextCommands -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages import io.github.freya022.botcommands.api.core.service.annotations.InjectedService import io.github.freya022.botcommands.api.core.utils.toImmutableList import io.github.freya022.botcommands.internal.core.config.ConfigDSL diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt similarity index 98% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt index cba55f944..4f41778ad 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessages.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt @@ -1,4 +1,4 @@ -package io.github.freya022.botcommands.api.core.replies +package io.github.freya022.botcommands.api.core.messages import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessagesFactory.kt similarity index 96% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessagesFactory.kt index b5e80293d..1cfaa5f56 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/BotCommandsMessagesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessagesFactory.kt @@ -1,6 +1,6 @@ @file:Suppress("DEPRECATION") -package io.github.freya022.botcommands.api.core.replies +package io.github.freya022.botcommands.api.core.messages import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt similarity index 97% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt index 715295314..55d537469 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessages.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt @@ -1,8 +1,8 @@ -package io.github.freya022.botcommands.api.core.replies +package io.github.freya022.botcommands.api.core.messages import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo -import io.github.freya022.botcommands.api.core.replies.exceptions.MissingReplyTemplateException +import io.github.freya022.botcommands.api.core.messages.exceptions.MissingReplyTemplateException import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService import io.github.freya022.botcommands.api.localization.LocalizationTemplate diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessagesFactory.kt similarity index 97% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessagesFactory.kt index 47df55ebe..9ab28e83b 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/DefaultBotCommandsMessagesFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessagesFactory.kt @@ -1,4 +1,4 @@ -package io.github.freya022.botcommands.api.core.replies +package io.github.freya022.botcommands.api.core.messages import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt similarity index 56% rename from src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt rename to src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt index 349a483e0..1636864ec 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/replies/exceptions/MissingReplyTemplateException.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt @@ -1,3 +1,3 @@ -package io.github.freya022.botcommands.api.core.replies.exceptions +package io.github.freya022.botcommands.api.core.messages.exceptions class MissingReplyTemplateException(message: String) : IllegalArgumentException(message) \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt index 45dc190db..107fafee4 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InterfacedService.kt @@ -14,7 +14,7 @@ import io.github.freya022.botcommands.api.components.ComponentInteractionFilter import io.github.freya022.botcommands.api.core.* import io.github.freya022.botcommands.api.core.db.ConnectionSupplier import io.github.freya022.botcommands.api.core.db.query.ParametrizedQueryFactory -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.localization.arguments.factories.FormattableArgumentFactory import io.github.freya022.botcommands.api.localization.providers.LocalizationMapProvider diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt index 1d2e978b6..7ec9e0c85 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizableAction.kt @@ -1,8 +1,8 @@ package io.github.freya022.botcommands.api.localization import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.context.LocalizationContext import io.github.freya022.botcommands.api.localization.context.PairEntry import io.github.freya022.botcommands.api.localization.context.mapToEntries diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt index 5b84a3f34..436128aaa 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/SlashParameterResolver.kt @@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.commands.application.slash.annotations import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.annotations.AutocompleteHandler import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.application.slash.options.builder.SlashCommandOptionBuilder -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages import io.github.freya022.botcommands.api.parameters.ParameterResolver import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt index e15421c9e..f96682562 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt @@ -15,8 +15,8 @@ import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.entities.inputUser -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.getMissingPermissions diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt index dc5308386..95959175c 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashCommandInfoImpl.kt @@ -5,7 +5,7 @@ import io.github.freya022.botcommands.api.commands.application.slash.GlobalSlash import io.github.freya022.botcommands.api.commands.application.slash.GuildSlashEvent import io.github.freya022.botcommands.api.commands.application.slash.SlashCommandInfo import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.* diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt index e1ec84ef1..a1067f024 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/handler/RateLimitHandler.kt @@ -5,7 +5,7 @@ import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimi import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.BotOwners import io.github.freya022.botcommands.api.core.config.BConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.loggerOf import io.github.freya022.botcommands.internal.commands.application.ApplicationCommandInfoImpl diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt index fbbe92826..507af8c93 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/HelpCommand.kt @@ -7,7 +7,7 @@ import io.github.freya022.botcommands.api.commands.text.annotations.RequiresText import io.github.freya022.botcommands.api.commands.text.provider.TextCommandManager import io.github.freya022.botcommands.api.commands.text.provider.TextCommandProvider import io.github.freya022.botcommands.api.core.config.BTextConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt index 7a52536c6..176d85e39 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt @@ -10,8 +10,8 @@ import io.github.freya022.botcommands.api.core.JDAService import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BTextConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt index 88656a258..6d5987214 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/controller/ComponentsListener.kt @@ -12,7 +12,7 @@ import io.github.freya022.botcommands.api.core.Filter import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.checkFilters import io.github.freya022.botcommands.api.core.config.BComponentsConfigBuilder -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.commands.ratelimit.handler.RateLimitHandler diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt index 42093346f..682efb3ce 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/ComponentHandlerExecutor.kt @@ -6,7 +6,7 @@ import io.github.freya022.botcommands.api.components.annotations.RequiresCompone import io.github.freya022.botcommands.api.components.event.EntitySelectEvent import io.github.freya022.botcommands.api.components.event.StringSelectEvent import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.core.utils.simpleNestedName import io.github.freya022.botcommands.internal.components.ComponentType diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt index 6f280b3aa..c74ef82fe 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt @@ -4,7 +4,7 @@ package io.github.freya022.botcommands.internal.core.replies import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages import io.github.freya022.botcommands.api.localization.DefaultMessages import net.dv8tion.jda.api.Permission import net.dv8tion.jda.api.events.GenericEvent diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt index 4a3a93e2e..5f5d63689 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt @@ -2,8 +2,8 @@ package io.github.freya022.botcommands.internal.core.replies -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.interactions.Interaction diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt index 4a678a684..42ad58d37 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.core.replies import io.github.classgraph.ClassGraph -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory -import io.github.freya022.botcommands.api.core.replies.DefaultBotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.DefaultBotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker import io.github.freya022.botcommands.api.core.service.ServiceContainer import io.github.freya022.botcommands.api.core.service.annotations.BService diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt index 21db71584..9c51765ce 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionFactory.kt @@ -3,7 +3,7 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt index d86561a6a..287f2740a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/interaction/LocalizableInteractionImpl.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.localization.interaction import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt index bf3862a52..a75a5aadd 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandFactory.kt @@ -3,7 +3,7 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.LocalizationService diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt index 7efd5cd0c..70850d5e7 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/text/LocalizableTextCommandImpl.kt @@ -3,8 +3,8 @@ package io.github.freya022.botcommands.internal.localization.text import io.github.freya022.botcommands.api.core.config.BLocalizationConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.api.localization.Localization diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt index b9bb12e0b..58eb24d35 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalListener.kt @@ -2,7 +2,7 @@ package io.github.freya022.botcommands.internal.modals import io.github.freya022.botcommands.api.core.annotations.BEventListener import io.github.freya022.botcommands.api.core.config.BModalsConfig -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.BService import io.github.freya022.botcommands.api.modals.ModalEvent import io.github.freya022.botcommands.api.modals.Modals diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt index 767f18764..b2b238b43 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/AbstractUserSnowflakeResolver.kt @@ -7,7 +7,7 @@ import io.github.freya022.botcommands.api.commands.text.options.TextCommandOptio import io.github.freya022.botcommands.api.components.options.ComponentOption import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData import io.github.freya022.botcommands.api.core.BContext -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.traceNull import io.github.freya022.botcommands.api.core.utils.retrieveMemberByIdOrNull diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/ChannelResolverFactory.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/ChannelResolverFactory.kt index b0204de9d..c7ae03dce 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/ChannelResolverFactory.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/ChannelResolverFactory.kt @@ -9,9 +9,9 @@ import io.github.freya022.botcommands.api.components.options.ComponentOption import io.github.freya022.botcommands.api.components.serialization.SerializedComponentData import io.github.freya022.botcommands.api.core.BContext import io.github.freya022.botcommands.api.core.exceptions.InvalidChannelTypeException +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.reflect.ParameterWrapper import io.github.freya022.botcommands.api.core.reflect.function -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.service.annotations.ResolverFactory import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.* diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt index 1f3633c1e..541b5790d 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt @@ -4,10 +4,10 @@ package io.github.freya022.botcommands.framework import io.github.freya022.botcommands.api.core.BotCommands import io.github.freya022.botcommands.api.core.config.registerServiceSupplier -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessages -import io.github.freya022.botcommands.api.core.replies.BotCommandsMessagesFactory -import io.github.freya022.botcommands.api.core.replies.DefaultBotCommandsMessagesFactory -import io.github.freya022.botcommands.api.core.replies.exceptions.MissingReplyTemplateException +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages +import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.DefaultBotCommandsMessagesFactory +import io.github.freya022.botcommands.api.core.messages.exceptions.MissingReplyTemplateException import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.joinAsList import io.github.freya022.botcommands.api.localization.DefaultMessages From e1f5ff07bb48a364c23e9bbea84ba642ac420bca Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Sun, 22 Jun 2025 17:47:01 +0200 Subject: [PATCH 17/21] Minor fixes --- ...tinReplies-default.json => BotCommandsMessages-default.json} | 0 .../freya022/botcommands/framework/BotCommandsMessagesTests.kt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/main/resources/bc_localization/{BuiltinReplies-default.json => BotCommandsMessages-default.json} (100%) diff --git a/src/main/resources/bc_localization/BuiltinReplies-default.json b/src/main/resources/bc_localization/BotCommandsMessages-default.json similarity index 100% rename from src/main/resources/bc_localization/BuiltinReplies-default.json rename to src/main/resources/bc_localization/BotCommandsMessages-default.json diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt index 541b5790d..e4164db5a 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt @@ -65,7 +65,7 @@ class BotCommandsMessagesTests { } @Test - fun `All built-in replies have defaults`() { + fun `All messages have defaults`() { val context = BotCommands.createTest { services { // Override the autoconfiguration so we don't unexpectedly use a different implementation From 07b1493dfa58fc017968e6a34a1de872a9385b44 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Mon, 23 Jun 2025 15:06:29 +0200 Subject: [PATCH 18/21] Fix inconsistencies --- .../handler/DefaultRateLimitHandler.kt | 12 +++++------ .../application/ApplicationCommandListener.kt | 4 ++-- .../commands/text/TextCommandsListener.kt | 4 ++-- ...tCommandsMessagesDefaultMessagesAdapter.kt | 2 +- ...gesFactoryDefaultMessagesFactoryAdapter.kt | 2 +- .../BotCommandsMessagesFactoryProvider.kt | 2 +- .../framework/BotCommandsMessagesTests.kt | 21 ++++++++++++------- 7 files changed, 27 insertions(+), 20 deletions(-) rename src/main/kotlin/io/github/freya022/botcommands/internal/core/{replies => messages}/BotCommandsMessagesDefaultMessagesAdapter.kt (98%) rename src/main/kotlin/io/github/freya022/botcommands/internal/core/{replies => messages}/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt (94%) rename src/main/kotlin/io/github/freya022/botcommands/internal/core/{replies => messages}/BotCommandsMessagesFactoryProvider.kt (98%) diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt index 378425aa0..4b70301bf 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/handler/DefaultRateLimitHandler.kt @@ -115,16 +115,16 @@ class DefaultRateLimitHandler( private fun getRateLimitMessage( event: Event, - replies: BotCommandsMessages, + messages: BotCommandsMessages, probe: ConsumptionProbe ): MessageCreateData { val deadline = Instant.now().plusNanos(probe.nanosToWaitForRefill) return when (scope) { - RateLimitScope.USER -> replies.userRateLimited(event, deadline) - RateLimitScope.USER_PER_GUILD -> replies.userRateLimited(event, deadline) - RateLimitScope.USER_PER_CHANNEL -> replies.userRateLimited(event, deadline) - RateLimitScope.GUILD -> replies.guildRateLimited(event, deadline) - RateLimitScope.CHANNEL -> replies.channelRateLimited(event, deadline) + RateLimitScope.USER -> messages.userRateLimited(event, deadline) + RateLimitScope.USER_PER_GUILD -> messages.userRateLimited(event, deadline) + RateLimitScope.USER_PER_CHANNEL -> messages.userRateLimited(event, deadline) + RateLimitScope.GUILD -> messages.guildRateLimited(event, deadline) + RateLimitScope.CHANNEL -> messages.channelRateLimited(event, deadline) } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt index f96682562..76d0243ea 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/ApplicationCommandListener.kt @@ -236,7 +236,7 @@ internal class ApplicationCommandListener internal constructor( private suspend fun canRun(event: GenericCommandInteractionEvent, applicationCommand: ApplicationCommandInfoImpl): Boolean { val usability = applicationCommand.getUsability(event.inputUser, event.messageChannel) if (usability.isNotUsable) { - val errorMessage = fromReplies(event) { + val errorMessage = fromMessages(event) { when (usability.bestReason) { UnusableReason.OWNER_ONLY -> ownerOnly(event) UnusableReason.USER_PERMISSIONS -> { @@ -280,7 +280,7 @@ internal class ApplicationCommandListener internal constructor( } } - private inline fun fromReplies(event: Interaction, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { + private inline fun fromMessages(event: Interaction, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { return messagesFactory.get(event).run(block) } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt index 176d85e39..3d47aaa46 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextCommandsListener.kt @@ -177,7 +177,7 @@ internal class TextCommandsListener internal constructor( val usability = commandInfo.getUsability(member, event.guildChannel) if (usability.isNotUsable) { - val errorMessage = fromReplies(event) { + val errorMessage = fromMessages(event) { when (usability.bestReason) { UnusableReason.HIDDEN -> throwInternal("Hidden commands should have been ignored by ${TextCommandsListener::findCommandWithArgs.shortSignature}") UnusableReason.OWNER_ONLY -> ownerOnly(event) @@ -249,7 +249,7 @@ internal class TextCommandsListener internal constructor( } } - private inline fun fromReplies(event: MessageReceivedEvent, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { + private inline fun fromMessages(event: MessageReceivedEvent, crossinline block: BotCommandsMessages.() -> MessageCreateData): MessageCreateData { return messagesFactory.get(event).run(block) } diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesDefaultMessagesAdapter.kt similarity index 98% rename from src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt rename to src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesDefaultMessagesAdapter.kt index c74ef82fe..c5634e18b 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesDefaultMessagesAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesDefaultMessagesAdapter.kt @@ -1,6 +1,6 @@ @file:Suppress("removal", "DEPRECATION") -package io.github.freya022.botcommands.internal.core.replies +package io.github.freya022.botcommands.internal.core.messages import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt similarity index 94% rename from src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt rename to src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt index 5f5d63689..9e397b590 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryDefaultMessagesFactoryAdapter.kt @@ -1,6 +1,6 @@ @file:Suppress("removal", "DEPRECATION") -package io.github.freya022.botcommands.internal.core.replies +package io.github.freya022.botcommands.internal.core.messages import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt similarity index 98% rename from src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt rename to src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt index 42ad58d37..72bd00ded 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/replies/BotCommandsMessagesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt @@ -1,6 +1,6 @@ @file:Suppress("DEPRECATION") -package io.github.freya022.botcommands.internal.core.replies +package io.github.freya022.botcommands.internal.core.messages import io.github.classgraph.ClassGraph import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt index e4164db5a..d47511a7c 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt @@ -13,7 +13,7 @@ import io.github.freya022.botcommands.api.core.utils.joinAsList import io.github.freya022.botcommands.api.localization.DefaultMessages import io.github.freya022.botcommands.api.localization.DefaultMessagesFactory import io.github.freya022.botcommands.framework.utils.createTest -import io.github.freya022.botcommands.internal.core.replies.BotCommandsMessagesFactoryProvider +import io.github.freya022.botcommands.internal.core.messages.BotCommandsMessagesFactoryProvider import io.mockk.every import io.mockk.mockk import io.mockk.slot @@ -53,7 +53,9 @@ class BotCommandsMessagesTests { services { registerServiceSupplier { mockk { - every { botCommandsMessagesFactory(any(), any(), any(), any(), any()) } answers { callOriginal() } + every { + botCommandsMessagesFactory(any(), any(), any(), any(), any()) + } answers { callOriginal() } every { this@mockk["hasCustomDefaultMessages"]() } returns true } @@ -69,19 +71,23 @@ class BotCommandsMessagesTests { val context = BotCommands.createTest { services { // Override the autoconfiguration so we don't unexpectedly use a different implementation - registerServiceSupplier(additionalTypes = setOf(BotCommandsMessagesFactory::class)) { context -> + registerServiceSupplier( + additionalTypes = setOf( + BotCommandsMessagesFactory::class, + ) + ) { context -> DefaultBotCommandsMessagesFactory( context.getService(), context.getService(), context.getService(), - context.getService() + context.getService(), ) } } } val templatePathSlot = slot() - val messages = spyk(context.getService().get(Locale.ROOT), recordPrivateCalls = true) { + val messages = spyk(context.getService().get(Locale.ROOT)) { every { this@spyk["getLocalizationTemplate"](capture(templatePathSlot)) } answers { callOriginal() } } @@ -110,7 +116,8 @@ class BotCommandsMessagesTests { methodCall(messages::modalExpired) { this(mockk()) }, ) - val missingTests = BotCommandsMessages::class.java.declaredMethods.mapTo(hashSetOf()) { it.name } - methodCalls.keys + val missingTests = + BotCommandsMessages::class.java.declaredMethods.mapTo(hashSetOf()) { it.name } - methodCalls.keys if (missingTests.isNotEmpty()) { fail("The following methods are missing tests:\n" + missingTests.joinAsList()) } @@ -132,7 +139,7 @@ class BotCommandsMessagesTests { private fun > methodCall( callableRef: F, - executor: F.() -> Unit + executor: F.() -> Unit, ): Pair Unit> { return callableRef.name to { executor(callableRef) } } From c85d3475b0465bc15664391e2776664ae55a6476 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Mon, 23 Jun 2025 15:19:09 +0200 Subject: [PATCH 19/21] Improve docs --- .../api/core/messages/BotCommandsMessages.kt | 22 +++++++++---------- .../messages/DefaultBotCommandsMessages.kt | 4 ++-- .../MissingMessageTemplateException.kt | 7 ++++++ .../MissingReplyTemplateException.kt | 3 --- .../framework/BotCommandsMessagesTests.kt | 4 ++-- 5 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingMessageTemplateException.kt delete mode 100644 src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt index 4f41778ad..f805db00a 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/BotCommandsMessages.kt @@ -9,7 +9,7 @@ import net.dv8tion.jda.api.utils.messages.MessageCreateData import java.time.Instant /** - * Returns the messages used by the framework, instance produced by [BotCommandsMessagesFactory]. + * Returns the messages used by the framework, instances are produced by [BotCommandsMessagesFactory]. * * @see BotCommandsMessagesFactory */ @@ -21,32 +21,32 @@ interface BotCommandsMessages { fun uncaughtException(event: GenericEvent?): MessageCreateData /** - * @return Message to display when the user does not have enough permissions + * @return Message to display when the user is missing [permissions][io.github.freya022.botcommands.api.commands.annotations.UserPermissions] */ fun missingUserPermissions(event: GenericEvent?, permissions: Set): MessageCreateData /** - * @return Message to display when the bot does not have enough permissions + * @return Message to display when the bot is missing [permissions][io.github.freya022.botcommands.api.commands.annotations.BotPermissions] */ fun missingBotPermissions(event: GenericEvent?, permissions: Set): MessageCreateData /** - * @return Message to display when the command is only usable by the owner + * @return Message to display when a text command is [only usable by the owner][io.github.freya022.botcommands.api.commands.text.annotations.RequireOwner] */ fun ownerOnly(event: GenericEvent?): MessageCreateData /** - * @return Message to display when the command is on per-user rate limit + * @return Message to display when a user has exceeded a command's [rate limit][io.github.freya022.botcommands.api.commands.annotations.RateLimit] */ fun userRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData /** - * @return Message to display when the command is on per-channel rate limit + * @return Message to display when a channel has exceeded a command's [rate limit][io.github.freya022.botcommands.api.commands.annotations.RateLimit] */ fun channelRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData /** - * @return Message to display when the command is on per-guild rate limit + * @return Message to display when a guild has exceeded a command's [rate limit][io.github.freya022.botcommands.api.commands.annotations.RateLimit] */ fun guildRateLimited(event: GenericEvent?, deadline: Instant): MessageCreateData @@ -66,7 +66,7 @@ interface BotCommandsMessages { fun resolverChannelNotFound(event: GenericEvent?, channelId: Long): MessageCreateData /** - * @return Message to display when a channel parameter could not be resolved + * @return Message to display when a channel parameter could be resolved but is not accessible (such as private threads) */ fun resolverChannelMissingAccess(event: GenericEvent?, channelId: Long): MessageCreateData @@ -86,17 +86,17 @@ interface BotCommandsMessages { fun closedDirectMessages(event: GenericEvent?): MessageCreateData /** - * @return Message to display when a command is used in a NSFW [IAgeRestrictedChannel] + * @return Message to display when a command is used in a NSFW [IAgeRestrictedChannel] (see [@NSFW][io.github.freya022.botcommands.api.commands.text.annotations.NSFW]) */ fun nsfwOnly(event: GenericEvent?): MessageCreateData /** - * @return Message to display when a user tries to use a component it cannot interact with + * @return Message to display when a user tries to use a component it isn't allowed to interact with */ fun componentNotAllowed(event: GenericEvent?): MessageCreateData /** - * @return Message to display when a user tries to use a component which has reached timeout while the bot was offline + * @return Message to display when a user tries to use a component which does not exist anymore */ fun componentExpired(event: GenericEvent?): MessageCreateData diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt index 55d537469..187593966 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/DefaultBotCommandsMessages.kt @@ -2,7 +2,7 @@ package io.github.freya022.botcommands.api.core.messages import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo -import io.github.freya022.botcommands.api.core.messages.exceptions.MissingReplyTemplateException +import io.github.freya022.botcommands.api.core.messages.exceptions.MissingMessageTemplateException import io.github.freya022.botcommands.api.localization.Localization import io.github.freya022.botcommands.api.localization.LocalizationService import io.github.freya022.botcommands.api.localization.LocalizationTemplate @@ -113,7 +113,7 @@ open class DefaultBotCommandsMessages( protected fun getLocalizationTemplate(path: String): LocalizationTemplate { val template = localization[path] - ?: throw MissingReplyTemplateException("Template '$path' could not be found, available keys: ${localization.keys}") + ?: throw MissingMessageTemplateException("Template '$path' could not be found, available keys: ${localization.keys}") return template } diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingMessageTemplateException.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingMessageTemplateException.kt new file mode 100644 index 000000000..b17b6c19e --- /dev/null +++ b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingMessageTemplateException.kt @@ -0,0 +1,7 @@ +package io.github.freya022.botcommands.api.core.messages.exceptions + +/** + * Exception thrown when a localization template could not be found + * by a [BotCommandsMessages][io.github.freya022.botcommands.api.core.messages.BotCommandsMessages] instance. + */ +class MissingMessageTemplateException(message: String) : IllegalArgumentException(message) \ No newline at end of file diff --git a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt b/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt deleted file mode 100644 index 1636864ec..000000000 --- a/src/main/kotlin/io/github/freya022/botcommands/api/core/messages/exceptions/MissingReplyTemplateException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.freya022.botcommands.api.core.messages.exceptions - -class MissingReplyTemplateException(message: String) : IllegalArgumentException(message) \ No newline at end of file diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt index d47511a7c..21b99bf74 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt @@ -7,7 +7,7 @@ import io.github.freya022.botcommands.api.core.config.registerServiceSupplier import io.github.freya022.botcommands.api.core.messages.BotCommandsMessages import io.github.freya022.botcommands.api.core.messages.BotCommandsMessagesFactory import io.github.freya022.botcommands.api.core.messages.DefaultBotCommandsMessagesFactory -import io.github.freya022.botcommands.api.core.messages.exceptions.MissingReplyTemplateException +import io.github.freya022.botcommands.api.core.messages.exceptions.MissingMessageTemplateException import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.core.utils.joinAsList import io.github.freya022.botcommands.api.localization.DefaultMessages @@ -127,7 +127,7 @@ class BotCommandsMessagesTests { templatePathSlot.clear() try { methodCall() - } catch (_: MissingReplyTemplateException) { + } catch (_: MissingMessageTemplateException) { methodsMissingTemplate += templatePathSlot.captured } } From 177eb3e95db155bead4408772b3274abe6a3f4c7 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:47:36 +0200 Subject: [PATCH 20/21] Move ConditionalOnMissingBean on bean factory --- .../core/messages/BotCommandsMessagesFactoryProvider.kt | 4 ++-- .../internal/localization/PermissionLocalizationProvider.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt index 72bd00ded..0cc86de04 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/core/messages/BotCommandsMessagesFactoryProvider.kt @@ -25,12 +25,12 @@ import org.springframework.context.annotation.Bean private val logger = KotlinLogging.logger { } -@AutoConfiguration -@ConditionalOnMissingBean(BotCommandsMessagesFactory::class) @BService +@AutoConfiguration internal open class BotCommandsMessagesFactoryProvider internal constructor() { @Bean + @ConditionalOnMissingBean(BotCommandsMessagesFactory::class) @BService @ConditionalService(ActivationCondition::class) open fun botCommandsMessagesFactory( diff --git a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt index a5eb7da8d..50046655d 100644 --- a/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt +++ b/src/main/kotlin/io/github/freya022/botcommands/internal/localization/PermissionLocalizationProvider.kt @@ -14,12 +14,12 @@ import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.context.annotation.Bean -@AutoConfiguration -@ConditionalOnMissingBean(PermissionLocalization::class) @BService +@AutoConfiguration internal open class PermissionLocalizationProvider internal constructor() { @Bean + @ConditionalOnMissingBean(PermissionLocalization::class) @BService @ConditionalService(ActivationCondition::class) open fun permissionLocalization(localizationService: LocalizationService): PermissionLocalization { From 3bf3845e230b234752a462abea7c2e3560352f6b Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:47:59 +0200 Subject: [PATCH 21/21] Test auto configurations can be overridden --- .../framework/BotCommandsMessagesTests.kt | 15 ++++++++++++++ .../framework/PermissionLocalizationTests.kt | 20 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt index 21b99bf74..0b3883075 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/BotCommandsMessagesTests.kt @@ -21,11 +21,13 @@ import io.mockk.spyk import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.interactions.Interaction import net.dv8tion.jda.api.utils.messages.MessageCreateData +import org.junit.jupiter.api.assertDoesNotThrow import java.time.Instant import java.util.* import kotlin.reflect.KFunction import kotlin.test.Test import kotlin.test.assertIsNot +import kotlin.test.assertSame import kotlin.test.fail class BotCommandsMessagesTests { @@ -66,6 +68,19 @@ class BotCommandsMessagesTests { assertIsNot(context.getService()) } + @Test + fun `Can override autoconfiguration`() { + val expected = mockk() + val context = BotCommands.createTest { + services { + registerServiceSupplier { expected } + } + } + + val actual = assertDoesNotThrow { context.getService() } + assertSame(expected, actual) + } + @Test fun `All messages have defaults`() { val context = BotCommands.createTest { diff --git a/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt b/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt index 7679506eb..e48ac674f 100644 --- a/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt +++ b/src/test/kotlin/io/github/freya022/botcommands/framework/PermissionLocalizationTests.kt @@ -1,13 +1,20 @@ package io.github.freya022.botcommands.framework +import io.github.freya022.botcommands.api.core.BotCommands +import io.github.freya022.botcommands.api.core.config.registerServiceSupplier +import io.github.freya022.botcommands.api.core.service.getService import io.github.freya022.botcommands.api.localization.DefaultPermissionLocalization import io.github.freya022.botcommands.api.localization.LocalizationService +import io.github.freya022.botcommands.api.localization.PermissionLocalization +import io.github.freya022.botcommands.framework.utils.createTest import io.mockk.every import io.mockk.mockk import net.dv8tion.jda.api.Permission +import org.junit.jupiter.api.assertDoesNotThrow import java.util.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertSame class PermissionLocalizationTests { @@ -35,4 +42,17 @@ class PermissionLocalizationTests { assertEquals(expected, actual) } + + @Test + fun `Can override autoconfiguration`() { + val expected = mockk() + val context = BotCommands.createTest { + services { + registerServiceSupplier { expected } + } + } + + val actual = assertDoesNotThrow { context.getService() } + assertSame(expected, actual) + } } \ No newline at end of file