├── .github ├── CONTRIBUTING.md ├── FUNDING.yml ├── SUPPORT.md └── workflows │ ├── check-javadoc.yml │ ├── check-kdocs.yml │ ├── docs.yml │ ├── jitpack-preview.yml │ └── maven-publish.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── BotCommands 3.X Live Templates.zip ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── command_help_embed_example.png ├── logo.svg └── slash_ban_example.gif ├── jitpack.yml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── rules.xml ├── src ├── examples │ ├── README.md │ ├── kotlin │ │ └── io │ │ │ └── github │ │ │ └── freya022 │ │ │ └── bot │ │ │ ├── Bot.kt │ │ │ ├── CoroutineEventManagerSupplier.kt │ │ │ ├── Main.kt │ │ │ ├── ReadyListener.kt │ │ │ ├── commands │ │ │ ├── ban │ │ │ │ └── BanService.kt │ │ │ ├── slash │ │ │ │ ├── SlashBan.kt │ │ │ │ ├── SlashButton.kt │ │ │ │ ├── SlashChoose.kt │ │ │ │ ├── SlashDelayedSelectMenu.kt │ │ │ │ ├── SlashModal.kt │ │ │ │ └── SlashSentence.kt │ │ │ └── text │ │ │ │ ├── HelpCommand.kt │ │ │ │ ├── TextExit.kt │ │ │ │ └── TextNumber.kt │ │ │ ├── config │ │ │ ├── Config.kt │ │ │ ├── Data.kt │ │ │ ├── DatabaseSource.kt │ │ │ └── Environment.kt │ │ │ ├── resolvers │ │ │ └── TimeUnitResolver.kt │ │ │ └── switches │ │ │ └── KotlinDetailProfile.kt │ └── resources │ │ └── bc_localization │ │ ├── Commands.json │ │ └── Commands_fr.json ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── freya022 │ │ │ └── botcommands │ │ │ ├── api │ │ │ ├── $BCInfo.java │ │ │ ├── commands │ │ │ │ ├── CommandPath.java │ │ │ │ ├── application │ │ │ │ │ ├── ApplicationGeneratedValueSupplier.java │ │ │ │ │ └── CommandScope.java │ │ │ │ ├── ratelimit │ │ │ │ │ └── RateLimitScope.java │ │ │ │ └── text │ │ │ │ │ ├── BaseCommandEvent.java │ │ │ │ │ ├── CommandEvent.java │ │ │ │ │ ├── HelpBuilderConsumer.java │ │ │ │ │ ├── IHelpCommand.kt │ │ │ │ │ ├── TextCommand.java │ │ │ │ │ ├── TextGeneratedValueSupplier.java │ │ │ │ │ └── exceptions │ │ │ │ │ ├── BadIdException.java │ │ │ │ │ └── NoIdException.java │ │ │ ├── core │ │ │ │ ├── DefaultEmbedFooterIconSupplier.java │ │ │ │ ├── DefaultEmbedSupplier.java │ │ │ │ ├── GlobalExceptionHandler.java │ │ │ │ ├── GlobalExceptionHandlerAdapter.java │ │ │ │ └── db │ │ │ │ │ ├── BlockingDatabase.java │ │ │ │ │ ├── BlockingTransaction.java │ │ │ │ │ ├── StatementFunction.java │ │ │ │ │ └── TransactionFunction.java │ │ │ ├── localization │ │ │ │ ├── DefaultMessages.java │ │ │ │ ├── Localization.java │ │ │ │ ├── LocalizationMapRequest.java │ │ │ │ ├── providers │ │ │ │ │ ├── DefaultLocalizationMapProvider.java │ │ │ │ │ ├── LocalizationMapProvider.java │ │ │ │ │ └── LocalizationMapProviders.java │ │ │ │ └── readers │ │ │ │ │ ├── LocalizationMapReader.java │ │ │ │ │ └── LocalizationMapReaders.java │ │ │ └── utils │ │ │ │ ├── EmojiUtils.java │ │ │ │ ├── RichTextConsumer.java │ │ │ │ ├── RichTextFinder.java │ │ │ │ └── RichTextType.java │ │ │ └── internal │ │ │ └── utils │ │ │ ├── ReflectionMetadataAccessor.java │ │ │ └── TimeoutExceptionAccessor.java │ ├── kotlin │ │ └── io │ │ │ └── github │ │ │ └── freya022 │ │ │ └── botcommands │ │ │ ├── api │ │ │ ├── ReceiverConsumer.kt │ │ │ ├── annotations │ │ │ │ └── CommandMarker.kt │ │ │ ├── commands │ │ │ │ ├── CommandInfo.kt │ │ │ │ ├── CommandType.kt │ │ │ │ ├── ICommandOptionContainer.kt │ │ │ │ ├── ICommandParameterContainer.kt │ │ │ │ ├── IFilterContainer.kt │ │ │ │ ├── INamedCommand.kt │ │ │ │ ├── IRateLimitHolder.kt │ │ │ │ ├── Usability.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── BotPermissions.kt │ │ │ │ │ ├── Command.kt │ │ │ │ │ ├── Cooldown.kt │ │ │ │ │ ├── Filter.kt │ │ │ │ │ ├── GeneratedOption.kt │ │ │ │ │ ├── Optional.kt │ │ │ │ │ ├── RateLimit.kt │ │ │ │ │ ├── UserPermissions.kt │ │ │ │ │ └── VarArgs.kt │ │ │ │ ├── application │ │ │ │ │ ├── ApplicationCommand.kt │ │ │ │ │ ├── ApplicationCommandFilter.kt │ │ │ │ │ ├── ApplicationCommandInfo.kt │ │ │ │ │ ├── ApplicationCommandResolverData.kt │ │ │ │ │ ├── ApplicationCommandsContext.kt │ │ │ │ │ ├── CommandDeclarationFilter.kt │ │ │ │ │ ├── CommandUpdateException.kt │ │ │ │ │ ├── CommandUpdateResult.kt │ │ │ │ │ ├── LengthRange.kt │ │ │ │ │ ├── TopLevelApplicationCommandInfo.kt │ │ │ │ │ ├── TopLevelApplicationCommandMetadata.kt │ │ │ │ │ ├── ValueRange.kt │ │ │ │ │ ├── annotations │ │ │ │ │ │ ├── CommandId.kt │ │ │ │ │ │ ├── DeclarationFilter.kt │ │ │ │ │ │ ├── RequiresApplicationCommands.kt │ │ │ │ │ │ └── Test.kt │ │ │ │ │ ├── builder │ │ │ │ │ │ ├── ApplicationCommandBuilder.kt │ │ │ │ │ │ └── TopLevelApplicationCommandBuilder.kt │ │ │ │ │ ├── context │ │ │ │ │ │ ├── annotations │ │ │ │ │ │ │ ├── ContextOption.kt │ │ │ │ │ │ │ ├── JDAMessageCommand.kt │ │ │ │ │ │ │ └── JDAUserCommand.kt │ │ │ │ │ │ ├── message │ │ │ │ │ │ │ ├── GlobalMessageEvent.kt │ │ │ │ │ │ │ ├── GuildMessageEvent.kt │ │ │ │ │ │ │ ├── MessageCommandInfo.kt │ │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ │ └── MessageCommandBuilder.kt │ │ │ │ │ │ │ └── options │ │ │ │ │ │ │ │ ├── MessageContextCommandOption.kt │ │ │ │ │ │ │ │ ├── MessageContextCommandParameter.kt │ │ │ │ │ │ │ │ └── builder │ │ │ │ │ │ │ │ ├── MessageCommandOptionAggregateBuilder.kt │ │ │ │ │ │ │ │ ├── MessageCommandOptionBuilder.kt │ │ │ │ │ │ │ │ └── MessageCommandOptionRegistry.kt │ │ │ │ │ │ ├── options │ │ │ │ │ │ │ ├── ContextCommandOption.kt │ │ │ │ │ │ │ └── ContextCommandParameter.kt │ │ │ │ │ │ └── user │ │ │ │ │ │ │ ├── GlobalUserEvent.kt │ │ │ │ │ │ │ ├── GuildUserEvent.kt │ │ │ │ │ │ │ ├── UserCommandInfo.kt │ │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ └── UserCommandBuilder.kt │ │ │ │ │ │ │ └── options │ │ │ │ │ │ │ ├── UserContextCommandOption.kt │ │ │ │ │ │ │ ├── UserContextCommandParameter.kt │ │ │ │ │ │ │ └── builder │ │ │ │ │ │ │ ├── UserCommandOptionAggregateBuilder.kt │ │ │ │ │ │ │ ├── UserCommandOptionBuilder.kt │ │ │ │ │ │ │ └── UserCommandOptionRegistry.kt │ │ │ │ │ ├── diff │ │ │ │ │ │ └── DiffEngine.kt │ │ │ │ │ ├── exceptions │ │ │ │ │ │ └── ApplicationCommandUpdateException.kt │ │ │ │ │ ├── options │ │ │ │ │ │ ├── ApplicationCommandOption.kt │ │ │ │ │ │ ├── ApplicationCommandParameter.kt │ │ │ │ │ │ └── builder │ │ │ │ │ │ │ ├── ApplicationCommandOptionAggregateBuilder.kt │ │ │ │ │ │ │ ├── ApplicationCommandOptionBuilder.kt │ │ │ │ │ │ │ └── ApplicationOptionRegistry.kt │ │ │ │ │ ├── provider │ │ │ │ │ │ ├── AbstractApplicationCommandManager.kt │ │ │ │ │ │ ├── GlobalApplicationCommandManager.kt │ │ │ │ │ │ ├── GlobalApplicationCommandProvider.kt │ │ │ │ │ │ ├── GuildApplicationCommandManager.kt │ │ │ │ │ │ └── GuildApplicationCommandProvider.kt │ │ │ │ │ └── slash │ │ │ │ │ │ ├── GlobalSlashEvent.kt │ │ │ │ │ │ ├── GuildSlashEvent.kt │ │ │ │ │ │ ├── SlashCommandInfo.kt │ │ │ │ │ │ ├── SlashSubcommandGroupInfo.kt │ │ │ │ │ │ ├── SlashSubcommandInfo.kt │ │ │ │ │ │ ├── TopLevelSlashCommandInfo.kt │ │ │ │ │ │ ├── annotations │ │ │ │ │ │ ├── ChannelTypes.kt │ │ │ │ │ │ ├── DoubleRange.kt │ │ │ │ │ │ ├── JDASlashCommand.kt │ │ │ │ │ │ ├── Length.kt │ │ │ │ │ │ ├── LongRange.kt │ │ │ │ │ │ ├── MentionsString.kt │ │ │ │ │ │ ├── SlashCommandGroupData.kt │ │ │ │ │ │ ├── SlashOption.kt │ │ │ │ │ │ └── TopLevelSlashCommandData.kt │ │ │ │ │ │ ├── autocomplete │ │ │ │ │ │ ├── AutocompleteAlgorithms.kt │ │ │ │ │ │ ├── AutocompleteMode.kt │ │ │ │ │ │ ├── AutocompleteTransformer.kt │ │ │ │ │ │ ├── FuzzyResult.kt │ │ │ │ │ │ ├── ToStringFunction.kt │ │ │ │ │ │ ├── annotations │ │ │ │ │ │ │ ├── AutocompleteHandler.kt │ │ │ │ │ │ │ └── CacheAutocomplete.kt │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ ├── AutocompleteCacheInfoBuilder.kt │ │ │ │ │ │ │ └── AutocompleteInfoBuilder.kt │ │ │ │ │ │ └── declaration │ │ │ │ │ │ │ ├── AutocompleteHandlerProvider.kt │ │ │ │ │ │ │ └── AutocompleteManager.kt │ │ │ │ │ │ ├── builder │ │ │ │ │ │ ├── SlashCommandBuilder.kt │ │ │ │ │ │ ├── SlashSubcommandBuilder.kt │ │ │ │ │ │ ├── SlashSubcommandGroupBuilder.kt │ │ │ │ │ │ └── TopLevelSlashCommandBuilder.kt │ │ │ │ │ │ └── options │ │ │ │ │ │ ├── SlashCommandOption.kt │ │ │ │ │ │ ├── SlashCommandParameter.kt │ │ │ │ │ │ └── builder │ │ │ │ │ │ ├── SlashCommandOptionAggregateBuilder.kt │ │ │ │ │ │ ├── SlashCommandOptionBuilder.kt │ │ │ │ │ │ └── SlashOptionRegistry.kt │ │ │ │ ├── builder │ │ │ │ │ ├── CommandBuilder.kt │ │ │ │ │ ├── ExecutableCommandBuilder.kt │ │ │ │ │ └── RateLimitBuilder.kt │ │ │ │ ├── options │ │ │ │ │ ├── CommandOption.kt │ │ │ │ │ ├── CommandParameter.kt │ │ │ │ │ └── builder │ │ │ │ │ │ ├── CommandOptionAggregateBuilder.kt │ │ │ │ │ │ └── CommandOptionBuilder.kt │ │ │ │ ├── ratelimit │ │ │ │ │ ├── AnnotatedRateLimiterFactory.kt │ │ │ │ │ ├── CancellableRateLimit.kt │ │ │ │ │ ├── RateLimitInfo.kt │ │ │ │ │ ├── RateLimiter.kt │ │ │ │ │ ├── bucket │ │ │ │ │ │ ├── BucketAccessor.kt │ │ │ │ │ │ ├── BucketConfigurationSupplier.kt │ │ │ │ │ │ ├── BucketKeySupplier.kt │ │ │ │ │ │ ├── Buckets.kt │ │ │ │ │ │ ├── InMemoryBucketAccessor.kt │ │ │ │ │ │ └── ProxyBucketAccessor.kt │ │ │ │ │ ├── declaration │ │ │ │ │ │ ├── RateLimitManager.kt │ │ │ │ │ │ └── RateLimitProvider.kt │ │ │ │ │ └── handler │ │ │ │ │ │ ├── DefaultRateLimitHandler.kt │ │ │ │ │ │ └── RateLimitHandler.kt │ │ │ │ └── text │ │ │ │ │ ├── TextCommandFilter.kt │ │ │ │ │ ├── TextCommandInfo.kt │ │ │ │ │ ├── TextCommandVariation.kt │ │ │ │ │ ├── TextCommandsContext.kt │ │ │ │ │ ├── TextPrefixSupplier.kt │ │ │ │ │ ├── TextSubcommandInfo.kt │ │ │ │ │ ├── TextSuggestionSupplier.kt │ │ │ │ │ ├── TopLevelTextCommandInfo.kt │ │ │ │ │ ├── annotations │ │ │ │ │ ├── Category.kt │ │ │ │ │ ├── Hidden.kt │ │ │ │ │ ├── ID.kt │ │ │ │ │ ├── JDATextCommandVariation.kt │ │ │ │ │ ├── NSFW.kt │ │ │ │ │ ├── RequireOwner.kt │ │ │ │ │ ├── RequiresTextCommands.kt │ │ │ │ │ ├── TextCommandData.kt │ │ │ │ │ └── TextOption.kt │ │ │ │ │ ├── builder │ │ │ │ │ ├── TextCommandBuilder.kt │ │ │ │ │ ├── TextCommandVariationBuilder.kt │ │ │ │ │ ├── TextSubcommandBuilder.kt │ │ │ │ │ └── TopLevelTextCommandBuilder.kt │ │ │ │ │ ├── options │ │ │ │ │ ├── TextCommandOption.kt │ │ │ │ │ ├── TextCommandParameter.kt │ │ │ │ │ └── builder │ │ │ │ │ │ ├── TextCommandOptionAggregateBuilder.kt │ │ │ │ │ │ ├── TextCommandOptionBuilder.kt │ │ │ │ │ │ └── TextOptionRegistry.kt │ │ │ │ │ └── provider │ │ │ │ │ ├── TextCommandManager.kt │ │ │ │ │ └── TextCommandProvider.kt │ │ │ ├── components │ │ │ │ ├── AbstractComponentFactory.kt │ │ │ │ ├── AwaitableComponent.kt │ │ │ │ ├── Button.kt │ │ │ │ ├── Buttons.kt │ │ │ │ ├── ComponentGroup.kt │ │ │ │ ├── ComponentInteractionFilter.kt │ │ │ │ ├── Components.kt │ │ │ │ ├── EntitySelectMenu.kt │ │ │ │ ├── IGroupHolder.kt │ │ │ │ ├── IdentifiableComponent.kt │ │ │ │ ├── SelectMenus.kt │ │ │ │ ├── StringSelectMenu.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── ComponentData.kt │ │ │ │ │ ├── ComponentTimeoutHandler.kt │ │ │ │ │ ├── GroupTimeoutHandler.kt │ │ │ │ │ ├── JDAButtonListener.kt │ │ │ │ │ ├── JDASelectMenuListener.kt │ │ │ │ │ ├── RequiresComponents.kt │ │ │ │ │ └── TimeoutData.kt │ │ │ │ ├── builder │ │ │ │ │ ├── BaseComponentBuilder.kt │ │ │ │ │ ├── IActionableComponent.kt │ │ │ │ │ ├── IComponentBuilder.kt │ │ │ │ │ ├── IConstrainableComponent.kt │ │ │ │ │ ├── ITimeoutableComponent.kt │ │ │ │ │ ├── IUniqueComponent.kt │ │ │ │ │ ├── button │ │ │ │ │ │ ├── ButtonBuilder.kt │ │ │ │ │ │ ├── ButtonFactory.kt │ │ │ │ │ │ ├── EphemeralButtonBuilder.kt │ │ │ │ │ │ └── PersistentButtonBuilder.kt │ │ │ │ │ ├── group │ │ │ │ │ │ ├── ComponentGroupBuilder.kt │ │ │ │ │ │ ├── ComponentGroupFactory.kt │ │ │ │ │ │ ├── EphemeralComponentGroupBuilder.kt │ │ │ │ │ │ └── PersistentComponentGroupBuilder.kt │ │ │ │ │ └── select │ │ │ │ │ │ ├── EntitySelectMenuFactory.kt │ │ │ │ │ │ ├── StringSelectMenuFactory.kt │ │ │ │ │ │ ├── ephemeral │ │ │ │ │ │ ├── EphemeralEntitySelectBuilder.kt │ │ │ │ │ │ └── EphemeralStringSelectBuilder.kt │ │ │ │ │ │ └── persistent │ │ │ │ │ │ ├── PersistentEntitySelectBuilder.kt │ │ │ │ │ │ └── PersistentStringSelectBuilder.kt │ │ │ │ ├── data │ │ │ │ │ ├── ComponentTimeoutData.kt │ │ │ │ │ ├── GroupTimeoutData.kt │ │ │ │ │ ├── ITimeoutData.kt │ │ │ │ │ └── InteractionConstraints.kt │ │ │ │ ├── event │ │ │ │ │ ├── ButtonEvent.kt │ │ │ │ │ ├── EntitySelectEvent.kt │ │ │ │ │ └── StringSelectEvent.kt │ │ │ │ ├── options │ │ │ │ │ └── ComponentOption.kt │ │ │ │ ├── ratelimit │ │ │ │ │ └── ComponentRateLimitReference.kt │ │ │ │ ├── serialization │ │ │ │ │ ├── GlobalComponentDataSerializer.kt │ │ │ │ │ ├── SerializedComponentData.kt │ │ │ │ │ ├── annotations │ │ │ │ │ │ ├── SerializableComponentData.kt │ │ │ │ │ │ └── SerializableTimeoutData.kt │ │ │ │ │ └── exceptions │ │ │ │ │ │ └── ComponentSerializationException.kt │ │ │ │ ├── timeout │ │ │ │ │ └── options │ │ │ │ │ │ └── TimeoutOption.kt │ │ │ │ └── utils │ │ │ │ │ ├── ButtonContent.kt │ │ │ │ │ └── SelectContent.kt │ │ │ ├── core │ │ │ │ ├── BContext.kt │ │ │ │ ├── BotCommands.kt │ │ │ │ ├── BotOwners.kt │ │ │ │ ├── DeclarationSite.kt │ │ │ │ ├── Executable.kt │ │ │ │ ├── Filter.kt │ │ │ │ ├── ICoroutineEventManagerSupplier.kt │ │ │ │ ├── IDeclarationSiteHolder.kt │ │ │ │ ├── JDAService.kt │ │ │ │ ├── Logging.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── BEventListener.kt │ │ │ │ │ ├── Handler.kt │ │ │ │ │ └── IgnoreStackFrame.kt │ │ │ │ ├── conditions │ │ │ │ │ └── RequiredIntents.kt │ │ │ │ ├── config │ │ │ │ │ ├── BAppEmojisConfig.kt │ │ │ │ │ ├── BApplicationConfig.kt │ │ │ │ │ ├── BComponentsConfig.kt │ │ │ │ │ ├── BConfig.kt │ │ │ │ │ ├── BCoroutineScopesConfig.kt │ │ │ │ │ ├── BDatabaseConfig.kt │ │ │ │ │ ├── BLocalizationConfig.kt │ │ │ │ │ ├── BModalsConfig.kt │ │ │ │ │ ├── BServiceConfig.kt │ │ │ │ │ ├── BTextConfig.kt │ │ │ │ │ ├── ConfigConfigurers.kt │ │ │ │ │ ├── DevConfig.kt │ │ │ │ │ ├── JDAConfiguration.kt │ │ │ │ │ └── application │ │ │ │ │ │ └── cache │ │ │ │ │ │ ├── ApplicationCommandsCacheConfig.kt │ │ │ │ │ │ ├── DatabaseApplicationCommandsCacheConfig.kt │ │ │ │ │ │ └── FileApplicationCommandsCacheConfig.kt │ │ │ │ ├── db │ │ │ │ │ ├── AbstractPreparedStatement.kt │ │ │ │ │ ├── BlockingPreparedStatement.kt │ │ │ │ │ ├── ConnectionSupplier.kt │ │ │ │ │ ├── DBResult.kt │ │ │ │ │ ├── Database.kt │ │ │ │ │ ├── HikariSourceSupplier.kt │ │ │ │ │ ├── PreparedStatements.kt │ │ │ │ │ ├── SuspendingPreparedStatement.kt │ │ │ │ │ ├── Transaction.kt │ │ │ │ │ ├── annotations │ │ │ │ │ │ └── RequiresDatabase.kt │ │ │ │ │ └── query │ │ │ │ │ │ ├── AbstractParametrizedQuery.kt │ │ │ │ │ │ ├── ParametrizedQuery.kt │ │ │ │ │ │ └── ParametrizedQueryFactory.kt │ │ │ │ ├── entities │ │ │ │ │ └── InputUser.kt │ │ │ │ ├── events │ │ │ │ │ ├── BEvent.kt │ │ │ │ │ ├── BGenericEvent.kt │ │ │ │ │ ├── BStatusChangeEvent.kt │ │ │ │ │ ├── FirstGuildReadyEvent.kt │ │ │ │ │ ├── InitializationEvents.kt │ │ │ │ │ ├── InjectedJDAEvent.kt │ │ │ │ │ └── PreFirstGatewayConnectEvent.kt │ │ │ │ ├── exceptions │ │ │ │ │ └── InvalidChannelTypeException.kt │ │ │ │ ├── hooks │ │ │ │ │ └── EventDispatcher.kt │ │ │ │ ├── options │ │ │ │ │ ├── Option.kt │ │ │ │ │ ├── annotations │ │ │ │ │ │ └── Aggregate.kt │ │ │ │ │ └── builder │ │ │ │ │ │ ├── OptionAggregateBuilder.kt │ │ │ │ │ │ ├── OptionAggregateBuilderContainer.kt │ │ │ │ │ │ ├── OptionBuilder.kt │ │ │ │ │ │ └── OptionRegistry.kt │ │ │ │ ├── reflect │ │ │ │ │ ├── KotlinTypeToken.kt │ │ │ │ │ ├── ParameterType.kt │ │ │ │ │ └── ParameterWrapper.kt │ │ │ │ ├── requests │ │ │ │ │ └── PriorityGlobalRestRateLimiter.kt │ │ │ │ ├── service │ │ │ │ │ ├── ClassGraphProcessor.kt │ │ │ │ │ ├── ConditionalServiceChecker.kt │ │ │ │ │ ├── CustomConditionChecker.kt │ │ │ │ │ ├── DefaultServiceContainer.kt │ │ │ │ │ ├── LazyService.kt │ │ │ │ │ ├── ServiceContainer.kt │ │ │ │ │ ├── ServiceResult.kt │ │ │ │ │ ├── ServiceSupplier.kt │ │ │ │ │ └── annotations │ │ │ │ │ │ ├── BConfiguration.kt │ │ │ │ │ │ ├── BService.kt │ │ │ │ │ │ ├── Condition.kt │ │ │ │ │ │ ├── ConditionalService.kt │ │ │ │ │ │ ├── Dependencies.kt │ │ │ │ │ │ ├── IgnoreServiceTypes.kt │ │ │ │ │ │ ├── InjectedService.kt │ │ │ │ │ │ ├── InterfacedService.kt │ │ │ │ │ │ ├── Lazy.kt │ │ │ │ │ │ ├── MissingServiceMessage.kt │ │ │ │ │ │ ├── Primary.kt │ │ │ │ │ │ ├── Resolver.kt │ │ │ │ │ │ ├── ResolverFactory.kt │ │ │ │ │ │ ├── ServiceName.kt │ │ │ │ │ │ ├── ServicePriority.kt │ │ │ │ │ │ └── ServiceType.kt │ │ │ │ ├── utils │ │ │ │ │ ├── Annotations.kt │ │ │ │ │ ├── Bucket4J.kt │ │ │ │ │ ├── ClassGraph.kt │ │ │ │ │ ├── Collections.kt │ │ │ │ │ ├── DefaultObjectMapper.kt │ │ │ │ │ ├── Emojis.kt │ │ │ │ │ ├── ErrorResponses.kt │ │ │ │ │ ├── JDA.kt │ │ │ │ │ ├── Jackson.kt │ │ │ │ │ ├── NIO.kt │ │ │ │ │ ├── Reflection.kt │ │ │ │ │ ├── RestResult.kt │ │ │ │ │ ├── Strings.kt │ │ │ │ │ └── Utils.kt │ │ │ │ └── waiter │ │ │ │ │ ├── CompletedFutureEvent.kt │ │ │ │ │ ├── EventWaiter.kt │ │ │ │ │ └── EventWaiterBuilder.kt │ │ │ ├── emojis │ │ │ │ ├── AppEmojisRegistry.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── AppEmoji.kt │ │ │ │ │ ├── AppEmojiContainer.kt │ │ │ │ │ └── RequiresAppEmojis.kt │ │ │ │ └── exceptions │ │ │ │ │ ├── EmojiAlreadyExistsException.kt │ │ │ │ │ ├── NoEmojiResourceException.kt │ │ │ │ │ ├── NonUniqueEmojiResourceException.kt │ │ │ │ │ └── OutOfAppEmojisException.kt │ │ │ ├── localization │ │ │ │ ├── DefaultLocalizationMap.kt │ │ │ │ ├── DefaultLocalizationTemplate.kt │ │ │ │ ├── DefaultMessagesFactory.kt │ │ │ │ ├── LocalizableAction.kt │ │ │ │ ├── Localization.kt │ │ │ │ ├── LocalizationMap.kt │ │ │ │ ├── LocalizationService.kt │ │ │ │ ├── LocalizationTemplate.kt │ │ │ │ ├── annotations │ │ │ │ │ └── LocalizationBundle.kt │ │ │ │ ├── arguments │ │ │ │ │ ├── FormattableArgument.kt │ │ │ │ │ ├── JavaFormattableArgument.kt │ │ │ │ │ ├── MessageFormatArgument.kt │ │ │ │ │ └── factories │ │ │ │ │ │ ├── FormattableArgumentFactory.kt │ │ │ │ │ │ ├── JavaFormattableArgumentFactory.kt │ │ │ │ │ │ └── MessageFormatArgumentFactory.kt │ │ │ │ ├── context │ │ │ │ │ ├── AppLocalizationContext.kt │ │ │ │ │ ├── LocalizationContext.kt │ │ │ │ │ └── TextLocalizationContext.kt │ │ │ │ ├── interaction │ │ │ │ │ ├── GuildLocaleProvider.kt │ │ │ │ │ ├── LocalizableEditCallback.kt │ │ │ │ │ ├── LocalizableInteraction.kt │ │ │ │ │ ├── LocalizableInteractionHook.kt │ │ │ │ │ ├── LocalizableReplyCallback.kt │ │ │ │ │ └── UserLocaleProvider.kt │ │ │ │ ├── readers │ │ │ │ │ ├── AbstractJacksonLocalizationMapReader.kt │ │ │ │ │ ├── JacksonLocalizationMapReader.kt │ │ │ │ │ ├── LocalizationTemplateFunction.kt │ │ │ │ │ └── provider │ │ │ │ │ │ └── DefaultLocalizationMapReaderProvider.kt │ │ │ │ └── text │ │ │ │ │ ├── LocalizableTextCommand.kt │ │ │ │ │ └── TextCommandLocaleProvider.kt │ │ │ ├── modals │ │ │ │ ├── Modal.kt │ │ │ │ ├── ModalBuilder.kt │ │ │ │ ├── ModalEvent.kt │ │ │ │ ├── Modals.kt │ │ │ │ ├── TextInputBuilder.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── ModalData.kt │ │ │ │ │ ├── ModalHandler.kt │ │ │ │ │ ├── ModalInput.kt │ │ │ │ │ └── RequiresModals.kt │ │ │ │ └── options │ │ │ │ │ └── ModalOption.kt │ │ │ ├── pagination │ │ │ │ ├── AbstractPagination.kt │ │ │ │ ├── AbstractPaginationBuilder.kt │ │ │ │ ├── PageEditor.kt │ │ │ │ ├── PaginationTimeoutConsumer.kt │ │ │ │ ├── Paginators.kt │ │ │ │ ├── TimeoutInfo.kt │ │ │ │ ├── UsedComponentSet.kt │ │ │ │ ├── custom │ │ │ │ │ ├── AbstractCustomPagination.kt │ │ │ │ │ ├── AbstractCustomPaginationBuilder.kt │ │ │ │ │ ├── CustomPageEditor.kt │ │ │ │ │ ├── CustomPagination.kt │ │ │ │ │ └── CustomPaginationBuilder.kt │ │ │ │ ├── menu │ │ │ │ │ ├── AbstractMenu.kt │ │ │ │ │ ├── AbstractMenuBuilder.kt │ │ │ │ │ ├── Menu.kt │ │ │ │ │ ├── MenuBuilder.kt │ │ │ │ │ ├── MenuPage.kt │ │ │ │ │ ├── RowPrefixSupplier.kt │ │ │ │ │ ├── buttonized │ │ │ │ │ │ ├── ButtonMenu.kt │ │ │ │ │ │ ├── ButtonMenuBuilder.kt │ │ │ │ │ │ └── ChoiceCallback.kt │ │ │ │ │ └── transformer │ │ │ │ │ │ ├── EntryTransformer.kt │ │ │ │ │ │ ├── IMentionableTransformer.kt │ │ │ │ │ │ └── StringTransformer.kt │ │ │ │ ├── nested │ │ │ │ │ ├── AbstractNestedPaginator.kt │ │ │ │ │ ├── AbstractNestedPaginatorBuilder.kt │ │ │ │ │ ├── NestedPaginationItem.kt │ │ │ │ │ ├── NestedPaginator.kt │ │ │ │ │ └── NestedPaginatorBuilder.kt │ │ │ │ └── paginator │ │ │ │ │ ├── AbstractPaginator.kt │ │ │ │ │ ├── AbstractPaginatorBuilder.kt │ │ │ │ │ ├── Paginator.kt │ │ │ │ │ └── PaginatorBuilder.kt │ │ │ └── parameters │ │ │ │ ├── AggregatedParameter.kt │ │ │ │ ├── ClassParameterResolver.kt │ │ │ │ ├── EnumResolver.kt │ │ │ │ ├── EnumResolverBuilder.kt │ │ │ │ ├── MethodParameter.kt │ │ │ │ ├── ParameterResolver.kt │ │ │ │ ├── ParameterResolverFactory.kt │ │ │ │ ├── ResolverData.kt │ │ │ │ ├── ResolverRequest.kt │ │ │ │ ├── Resolvers.kt │ │ │ │ ├── TypedParameterResolver.kt │ │ │ │ ├── TypedParameterResolverFactory.kt │ │ │ │ └── resolvers │ │ │ │ ├── ComponentParameterResolver.kt │ │ │ │ ├── ICustomResolver.kt │ │ │ │ ├── IParameterResolver.kt │ │ │ │ ├── MessageContextParameterResolver.kt │ │ │ │ ├── ModalParameterResolver.kt │ │ │ │ ├── QuotableTextParameterResolver.kt │ │ │ │ ├── SlashParameterResolver.kt │ │ │ │ ├── TextParameterResolver.kt │ │ │ │ ├── TimeoutParameterResolver.kt │ │ │ │ └── UserContextParameterResolver.kt │ │ │ ├── autoconfigure │ │ │ └── BotCommandsAutoConfiguration.kt │ │ │ └── internal │ │ │ ├── ExecutableMixin.kt │ │ │ ├── commands │ │ │ ├── AbstractCommandInfoImpl.kt │ │ │ ├── CommandDSL.kt │ │ │ ├── CommandPathImpl.kt │ │ │ ├── CommandsPresenceChecker.kt │ │ │ ├── SkipLogger.kt │ │ │ ├── UsabilityImpl.kt │ │ │ ├── application │ │ │ │ ├── ApplicationCommandInfoImpl.kt │ │ │ │ ├── ApplicationCommandListener.kt │ │ │ │ ├── ApplicationCommandsBuilder.kt │ │ │ │ ├── ApplicationCommandsContextImpl.kt │ │ │ │ ├── ApplicationCommandsUpdateRateLimiter.kt │ │ │ │ ├── ApplicationCommandsUpdater.kt │ │ │ │ ├── ApplicationUpdaterListener.kt │ │ │ │ ├── NamedCommandMap.kt │ │ │ │ ├── RequiresApplicationCommandsChecker.kt │ │ │ │ ├── TopLevelApplicationCommandMetadataImpl.kt │ │ │ │ ├── autobuilder │ │ │ │ │ ├── ContextCommandAutoBuilder.kt │ │ │ │ │ ├── MessageContextCommandAutoBuilder.kt │ │ │ │ │ ├── SlashCommandAutoBuilder.kt │ │ │ │ │ ├── UserContextCommandAutoBuilder.kt │ │ │ │ │ ├── metadata │ │ │ │ │ │ ├── ApplicationFunctionMetadata.kt │ │ │ │ │ │ ├── MessageContextFunctionMetadata.kt │ │ │ │ │ │ ├── SlashFunctionMetadata.kt │ │ │ │ │ │ └── UserContextFunctionMetadata.kt │ │ │ │ │ └── utils │ │ │ │ │ │ └── ParameterAdapter.kt │ │ │ │ ├── builder │ │ │ │ │ └── ApplicationCommandBuilderImpl.kt │ │ │ │ ├── cache │ │ │ │ │ ├── ApplicationCommandsCache.kt │ │ │ │ │ ├── ApplicationCommandsData.kt │ │ │ │ │ ├── DatabaseApplicationCommandsCache.kt │ │ │ │ │ ├── FileApplicationCommandsCache.kt │ │ │ │ │ ├── MemoryApplicationCommandsCache.kt │ │ │ │ │ ├── NullApplicationCommandsCache.kt │ │ │ │ │ ├── factory │ │ │ │ │ │ ├── ApplicationCommandsCacheFactory.kt │ │ │ │ │ │ ├── DatabaseApplicationCommandsCacheFactory.kt │ │ │ │ │ │ ├── FileApplicationCommandsCacheFactory.kt │ │ │ │ │ │ ├── MemoryApplicationCommandsCacheFactory.kt │ │ │ │ │ │ └── NullApplicationCommandsCacheFactory.kt │ │ │ │ │ └── provider │ │ │ │ │ │ └── ApplicationCommandsCacheFactoryProvider.kt │ │ │ │ ├── context │ │ │ │ │ ├── message │ │ │ │ │ │ ├── MessageCommandInfoImpl.kt │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ └── MessageCommandBuilderImpl.kt │ │ │ │ │ │ └── options │ │ │ │ │ │ │ ├── MessageContextCommandOptionImpl.kt │ │ │ │ │ │ │ ├── MessageContextCommandParameterImpl.kt │ │ │ │ │ │ │ └── builder │ │ │ │ │ │ │ ├── MessageCommandOptionAggregateBuilderImpl.kt │ │ │ │ │ │ │ └── MessageCommandOptionBuilderImpl.kt │ │ │ │ │ ├── options │ │ │ │ │ │ ├── ContextCommandOptionImpl.kt │ │ │ │ │ │ └── ContextCommandParameterImpl.kt │ │ │ │ │ └── user │ │ │ │ │ │ ├── UserCommandInfoImpl.kt │ │ │ │ │ │ ├── builder │ │ │ │ │ │ └── UserCommandBuilderImpl.kt │ │ │ │ │ │ └── options │ │ │ │ │ │ ├── UserContextCommandOptionImpl.kt │ │ │ │ │ │ ├── UserContextCommandParameterImpl.kt │ │ │ │ │ │ └── builder │ │ │ │ │ │ ├── UserCommandOptionAggregateBuilderImpl.kt │ │ │ │ │ │ └── UserCommandOptionBuilderImpl.kt │ │ │ │ ├── diff │ │ │ │ │ ├── ApplicationCommandDiffEngine.kt │ │ │ │ │ ├── DiffLogger.kt │ │ │ │ │ └── NewApplicationCommandDiffEngine.kt │ │ │ │ ├── localization │ │ │ │ │ └── BCLocalizationFunction.kt │ │ │ │ ├── mixins │ │ │ │ │ └── TopLevelApplicationCommandInfoMixin.kt │ │ │ │ ├── options │ │ │ │ │ ├── ApplicationCommandOptionImpl.kt │ │ │ │ │ ├── ApplicationCommandParameterImpl.kt │ │ │ │ │ ├── ApplicationGeneratedOption.kt │ │ │ │ │ └── builder │ │ │ │ │ │ ├── ApplicationCommandOptionAggregateBuilderImpl.kt │ │ │ │ │ │ ├── ApplicationCommandOptionBuilderImpl.kt │ │ │ │ │ │ └── ApplicationGeneratedOptionBuilderImpl.kt │ │ │ │ └── slash │ │ │ │ │ ├── SlashCommandInfoImpl.kt │ │ │ │ │ ├── SlashSubcommandGroupInfoImpl.kt │ │ │ │ │ ├── SlashSubcommandInfoImpl.kt │ │ │ │ │ ├── SlashUtils.kt │ │ │ │ │ ├── TopLevelSlashCommandInfoImpl.kt │ │ │ │ │ ├── autocomplete │ │ │ │ │ ├── AutocompleteCacheInfo.kt │ │ │ │ │ ├── AutocompleteHandler.kt │ │ │ │ │ ├── AutocompleteInfo.kt │ │ │ │ │ ├── AutocompleteInfoAutoBuilder.kt │ │ │ │ │ ├── AutocompleteInfoContainer.kt │ │ │ │ │ ├── AutocompleteInfoImpl.kt │ │ │ │ │ ├── AutocompleteListener.kt │ │ │ │ │ ├── CompositeAutocompleteKey.kt │ │ │ │ │ ├── builder │ │ │ │ │ │ ├── AutocompleteCacheInfoBuilderImpl.kt │ │ │ │ │ │ └── AutocompleteInfoBuilderImpl.kt │ │ │ │ │ ├── caches │ │ │ │ │ │ ├── AbstractAutocompleteCache.kt │ │ │ │ │ │ ├── BaseAutocompleteCache.kt │ │ │ │ │ │ ├── ConstantByKeyAutocompleteCache.kt │ │ │ │ │ │ └── NoCacheAutocomplete.kt │ │ │ │ │ ├── declaration │ │ │ │ │ │ ├── AutocompleteDeclarationRunner.kt │ │ │ │ │ │ └── AutocompleteManagerImpl.kt │ │ │ │ │ ├── options │ │ │ │ │ │ └── AutocompleteCommandParameterImpl.kt │ │ │ │ │ └── suppliers │ │ │ │ │ │ ├── ChoiceSupplier.kt │ │ │ │ │ │ ├── ChoiceSupplierChoices.kt │ │ │ │ │ │ ├── ChoiceSupplierStringContinuity.kt │ │ │ │ │ │ ├── ChoiceSupplierStringFuzzy.kt │ │ │ │ │ │ └── ChoiceSupplierTransformer.kt │ │ │ │ │ ├── builder │ │ │ │ │ ├── SlashCommandBuilderImpl.kt │ │ │ │ │ ├── SlashSubcommandBuilderImpl.kt │ │ │ │ │ ├── SlashSubcommandGroupBuilderImpl.kt │ │ │ │ │ ├── TopLevelSlashCommandBuilderImpl.kt │ │ │ │ │ └── mixins │ │ │ │ │ │ ├── TopLevelApplicationCommandBuilderMixin.kt │ │ │ │ │ │ └── TopLevelApplicationCommandBuilderMixinImpl.kt │ │ │ │ │ ├── exceptions │ │ │ │ │ └── OptionNotFoundException.kt │ │ │ │ │ └── options │ │ │ │ │ ├── SlashCommandOptionImpl.kt │ │ │ │ │ ├── SlashCommandOptionMixin.kt │ │ │ │ │ ├── SlashCommandParameterImpl.kt │ │ │ │ │ └── builder │ │ │ │ │ ├── SlashCommandOptionAggregateBuilderImpl.kt │ │ │ │ │ └── SlashCommandOptionBuilderImpl.kt │ │ │ ├── autobuilder │ │ │ │ ├── AutoBuilderUtils.kt │ │ │ │ ├── CommandAutoBuilder.kt │ │ │ │ └── metadata │ │ │ │ │ ├── CommandFunctionMetadata.kt │ │ │ │ │ └── MetadataFunctionHolder.kt │ │ │ ├── builder │ │ │ │ ├── CommandBuilderImpl.kt │ │ │ │ ├── ExecutableCommandBuilderImpl.kt │ │ │ │ ├── IBuilderFunctionHolder.kt │ │ │ │ └── RateLimitBuilderImpl.kt │ │ │ ├── options │ │ │ │ ├── CommandOptionImpl.kt │ │ │ │ ├── CommandParameterImpl.kt │ │ │ │ └── builder │ │ │ │ │ ├── CommandOptionAggregateBuilderImpl.kt │ │ │ │ │ └── CommandOptionBuilderImpl.kt │ │ │ ├── ratelimit │ │ │ │ ├── CancellableRateLimitImpl.kt │ │ │ │ ├── DefaultAnnotatedRateLimiterFactory.kt │ │ │ │ ├── DefaultProxyRateLimiter.kt │ │ │ │ ├── DefaultRateLimiter.kt │ │ │ │ ├── NullCancellableRateLimit.kt │ │ │ │ ├── RateLimitAnnotations.kt │ │ │ │ ├── RateLimitContainer.kt │ │ │ │ ├── declaration │ │ │ │ │ ├── RateLimitDeclarationRunner.kt │ │ │ │ │ └── RateLimitManagerImpl.kt │ │ │ │ └── handler │ │ │ │ │ └── RateLimitHandler.kt │ │ │ └── text │ │ │ │ ├── BaseCommandEventImpl.kt │ │ │ │ ├── CommandEventImpl.kt │ │ │ │ ├── CommandPattern.kt │ │ │ │ ├── DefaultTextSuggestionSupplierProvider.kt │ │ │ │ ├── ExecutionResult.kt │ │ │ │ ├── HelpCommand.kt │ │ │ │ ├── RequiresTextCommandsChecker.kt │ │ │ │ ├── TextCommandComparator.kt │ │ │ │ ├── TextCommandInfoImpl.kt │ │ │ │ ├── TextCommandStatusLogger.kt │ │ │ │ ├── TextCommandVariationImpl.kt │ │ │ │ ├── TextCommandsBuilder.kt │ │ │ │ ├── TextCommandsContextImpl.kt │ │ │ │ ├── TextCommandsListener.kt │ │ │ │ ├── TextSubcommandInfoImpl.kt │ │ │ │ ├── TextUtils.kt │ │ │ │ ├── TopLevelTextCommandInfoImpl.kt │ │ │ │ ├── autobuilder │ │ │ │ ├── TextCommandAutoBuilder.kt │ │ │ │ └── metadata │ │ │ │ │ └── TextFunctionMetadata.kt │ │ │ │ ├── builder │ │ │ │ ├── TextCommandBuilderImpl.kt │ │ │ │ ├── TextCommandVariationBuilderImpl.kt │ │ │ │ ├── TextSubcommandBuilderImpl.kt │ │ │ │ └── TopLevelTextCommandBuilderImpl.kt │ │ │ │ └── options │ │ │ │ ├── TextCommandOptionImpl.kt │ │ │ │ ├── TextCommandParameterImpl.kt │ │ │ │ ├── TextGeneratedOption.kt │ │ │ │ └── builder │ │ │ │ ├── TextCommandOptionAggregateBuilderImpl.kt │ │ │ │ ├── TextCommandOptionBuilderImpl.kt │ │ │ │ └── TextGeneratedOptionBuilderImpl.kt │ │ │ ├── components │ │ │ ├── AbstractAwaitableComponent.kt │ │ │ ├── ButtonImpl.kt │ │ │ ├── ComponentDSL.kt │ │ │ ├── ComponentType.kt │ │ │ ├── EntitySelectMenuImpl.kt │ │ │ ├── EphemeralHandlers.kt │ │ │ ├── IGroupHolderMixin.kt │ │ │ ├── LifetimeType.kt │ │ │ ├── RequiresComponentsChecker.kt │ │ │ ├── StringSelectMenuImpl.kt │ │ │ ├── builder │ │ │ │ ├── AbstractActionableComponent.kt │ │ │ │ ├── AbstractComponentBuilder.kt │ │ │ │ ├── BuilderInstanceHolder.kt │ │ │ │ ├── BuilderInstanceHolderImpl.kt │ │ │ │ ├── InstanceRetriever.kt │ │ │ │ ├── button │ │ │ │ │ ├── AbstractButtonBuilder.kt │ │ │ │ │ ├── EphemeralButtonBuilderImpl.kt │ │ │ │ │ └── PersistentButtonBuilderImpl.kt │ │ │ │ ├── group │ │ │ │ │ ├── AbstractComponentGroupBuilder.kt │ │ │ │ │ ├── EphemeralComponentGroupBuilderImpl.kt │ │ │ │ │ └── PersistentComponentGroupBuilderImpl.kt │ │ │ │ ├── mixin │ │ │ │ │ ├── BaseComponentBuilderMixin.kt │ │ │ │ │ ├── IActionableComponentMixin.kt │ │ │ │ │ ├── IComponentBuilderMixin.kt │ │ │ │ │ ├── IConstrainableComponentMixin.kt │ │ │ │ │ ├── ITimeoutableComponentMixin.kt │ │ │ │ │ ├── IUniqueComponentMixin.kt │ │ │ │ │ └── impl │ │ │ │ │ │ ├── ConstrainableComponentImpl.kt │ │ │ │ │ │ ├── EphemeralActionableComponentImpl.kt │ │ │ │ │ │ ├── EphemeralTimeoutableComponentImpl.kt │ │ │ │ │ │ ├── PersistentActionableComponentImpl.kt │ │ │ │ │ │ ├── PersistentTimeoutableComponentImpl.kt │ │ │ │ │ │ └── UniqueComponentImpl.kt │ │ │ │ └── select │ │ │ │ │ ├── ephemeral │ │ │ │ │ ├── EphemeralEntitySelectBuilderImpl.kt │ │ │ │ │ └── EphemeralStringSelectBuilderImpl.kt │ │ │ │ │ └── persistent │ │ │ │ │ ├── PersistentEntitySelectBuilderImpl.kt │ │ │ │ │ └── PersistentStringSelectBuilderImpl.kt │ │ │ ├── controller │ │ │ │ ├── ComponentContinuationManager.kt │ │ │ │ ├── ComponentController.kt │ │ │ │ ├── ComponentFilters.kt │ │ │ │ ├── ComponentTimeoutManager.kt │ │ │ │ └── ComponentsListener.kt │ │ │ ├── data │ │ │ │ ├── ActionComponentData.kt │ │ │ │ ├── ComponentData.kt │ │ │ │ ├── ComponentGroupData.kt │ │ │ │ ├── EphemeralComponentData.kt │ │ │ │ ├── PersistentComponentData.kt │ │ │ │ └── timeout │ │ │ │ │ ├── ComponentTimeout.kt │ │ │ │ │ ├── EphemeralTimeout.kt │ │ │ │ │ └── PersistentTimeout.kt │ │ │ ├── handler │ │ │ │ ├── ComponentDescriptor.kt │ │ │ │ ├── ComponentHandler.kt │ │ │ │ ├── ComponentHandlerContainer.kt │ │ │ │ ├── ComponentHandlerExecutor.kt │ │ │ │ ├── ComponentTimeoutExecutor.kt │ │ │ │ ├── EphemeralComponentHandlers.kt │ │ │ │ └── options │ │ │ │ │ ├── ComponentHandlerOption.kt │ │ │ │ │ ├── ComponentHandlerParameterImpl.kt │ │ │ │ │ └── builder │ │ │ │ │ └── ComponentHandlerOptionBuilderImpl.kt │ │ │ ├── repositories │ │ │ │ ├── ComponentHandlerRepository.kt │ │ │ │ ├── ComponentRepository.kt │ │ │ │ └── ComponentTimeoutRepository.kt │ │ │ ├── serialization │ │ │ │ ├── DefaultGlobalComponentDataSerializerProvider.kt │ │ │ │ └── resolver │ │ │ │ │ └── SerializableComponentDataResolverFactory.kt │ │ │ └── timeout │ │ │ │ ├── ComponentTimeoutHandlers.kt │ │ │ │ ├── EphemeralTimeoutHandlers.kt │ │ │ │ ├── GroupTimeoutHandlers.kt │ │ │ │ ├── TimeoutDescriptor.kt │ │ │ │ ├── TimeoutHandlerContainer.kt │ │ │ │ └── options │ │ │ │ ├── TimeoutHandlerOption.kt │ │ │ │ ├── TimeoutHandlerParameter.kt │ │ │ │ └── builder │ │ │ │ └── TimeoutHandlerOptionBuilderImpl.kt │ │ │ ├── core │ │ │ ├── BContextImpl.kt │ │ │ ├── BotOwnersImpl.kt │ │ │ ├── ClassPathFunction.kt │ │ │ ├── DefaultCoroutineEventManagerSupplierProvider.kt │ │ │ ├── ExceptionHandler.kt │ │ │ ├── HandlersPresenceChecker.kt │ │ │ ├── JDAInitListener.kt │ │ │ ├── JDARestLimiterChecker.kt │ │ │ ├── JDAServiceMismatchChecker.kt │ │ │ ├── ReadyListener.kt │ │ │ ├── SingleLogger.kt │ │ │ ├── SpringBotCommandsConfiguration.kt │ │ │ ├── SpringBotCommandsInitializer.kt │ │ │ ├── SpringJDARestartListener.kt │ │ │ ├── Version.kt │ │ │ ├── annotations │ │ │ │ └── InternalComponentScan.kt │ │ │ ├── conditions │ │ │ │ └── RequiredIntentsChecker.kt │ │ │ ├── config │ │ │ │ ├── BotCommandsConfigurations.kt │ │ │ │ ├── ConfigDSL.kt │ │ │ │ ├── ConfigProvider.kt │ │ │ │ ├── ConfigurationAnnotations.kt │ │ │ │ └── DefaultSearchPathConfigurer.kt │ │ │ ├── db │ │ │ │ ├── DatabaseImpl.kt │ │ │ │ ├── InternalDatabase.kt │ │ │ │ ├── query │ │ │ │ │ ├── GenericParametrizedQueryFactory.kt │ │ │ │ │ ├── NonParametrizedQueryFactory.kt │ │ │ │ │ └── PostgresParametrizedQueryFactory.kt │ │ │ │ └── traced │ │ │ │ │ ├── TracedConnection.kt │ │ │ │ │ └── TracedPreparedStatement.kt │ │ │ ├── entities │ │ │ │ └── InputUserImpl.kt │ │ │ ├── exceptions │ │ │ │ ├── InitializationException.kt │ │ │ │ ├── InternalException.kt │ │ │ │ └── ServiceException.kt │ │ │ ├── hooks │ │ │ │ ├── DispatcherAwareCoroutineEventManager.kt │ │ │ │ ├── EventDispatcherImpl.kt │ │ │ │ ├── EventHandlerFunction.kt │ │ │ │ ├── EventHooksProvider.kt │ │ │ │ ├── EventListenerList.kt │ │ │ │ ├── EventListenerRegistry.kt │ │ │ │ └── EventTreeService.kt │ │ │ ├── options │ │ │ │ ├── AbstractGeneratedOption.kt │ │ │ │ ├── OptionImpl.kt │ │ │ │ ├── OptionType.kt │ │ │ │ └── builder │ │ │ │ │ ├── AbstractGeneratedOptionBuilderImpl.kt │ │ │ │ │ ├── CustomOptionBuilderImpl.kt │ │ │ │ │ ├── InternalAggregators.kt │ │ │ │ │ ├── OptionAggregateBuilderContainerMixin.kt │ │ │ │ │ ├── OptionAggregateBuilderContainerMixinImpl.kt │ │ │ │ │ ├── OptionAggregateBuilderImpl.kt │ │ │ │ │ ├── OptionBuilderImpl.kt │ │ │ │ │ └── ServiceOptionBuilderImpl.kt │ │ │ ├── reflection │ │ │ │ ├── AggregatorFunction.kt │ │ │ │ ├── Function.kt │ │ │ │ ├── MemberFunction.kt │ │ │ │ ├── MemberParamFunction.kt │ │ │ │ └── ParameterMap.kt │ │ │ ├── service │ │ │ │ ├── AbstractBotCommandsBootstrap.kt │ │ │ │ ├── BotCommandsBootstrap.kt │ │ │ │ ├── ClassAnnotationsMap.kt │ │ │ │ ├── ConditionalObjectChecker.kt │ │ │ │ ├── DefaultBotCommandsBootstrap.kt │ │ │ │ ├── DefaultInjectionCondition.kt │ │ │ │ ├── DefaultServiceContainerImpl.kt │ │ │ │ ├── FunctionAnnotationsMap.kt │ │ │ │ ├── InstantiableServices.kt │ │ │ │ ├── LazyServiceImpl.kt │ │ │ │ ├── Singletons.kt │ │ │ │ ├── SpringBotCommandsBootstrap.kt │ │ │ │ ├── SpringServiceContainer.kt │ │ │ │ ├── annotations │ │ │ │ │ ├── HardcodedCondition.kt │ │ │ │ │ └── RequiresDefaultInjection.kt │ │ │ │ ├── provider │ │ │ │ │ ├── ClassServiceProvider.kt │ │ │ │ │ ├── FunctionServiceProvider.kt │ │ │ │ │ ├── ProvidedServiceProvider.kt │ │ │ │ │ ├── ServiceProvider.kt │ │ │ │ │ ├── ServiceProviders.kt │ │ │ │ │ └── SuppliedServiceProvider.kt │ │ │ │ └── stack │ │ │ │ │ ├── DefaultServiceCreationStack.kt │ │ │ │ │ ├── ServiceCreationStack.kt │ │ │ │ │ └── TracedServiceCreationStack.kt │ │ │ └── waiter │ │ │ │ ├── EventWaiterBuilderImpl.kt │ │ │ │ ├── EventWaiterImpl.kt │ │ │ │ └── WaitingEvent.kt │ │ │ ├── emojis │ │ │ ├── AppEmojiContainerData.kt │ │ │ ├── AppEmojiContainerProcessor.kt │ │ │ ├── AppEmojisLoader.kt │ │ │ └── RequiresAppEmojisChecker.kt │ │ │ ├── localization │ │ │ ├── AbstractLocalizableAction.kt │ │ │ ├── DefaultDefaultMessagesFactoryProvider.kt │ │ │ ├── LocalizableArgument.kt │ │ │ ├── LocalizationContextImpl.kt │ │ │ ├── LocalizationImpl.kt │ │ │ ├── LocalizationServiceImpl.kt │ │ │ ├── RawArgument.kt │ │ │ ├── SimpleArgument.kt │ │ │ ├── interaction │ │ │ │ ├── DefaultInteractionLocaleProviders.kt │ │ │ │ ├── LocalizableEditCallbackImpl.kt │ │ │ │ ├── LocalizableInteractionFactory.kt │ │ │ │ ├── LocalizableInteractionHookImpl.kt │ │ │ │ ├── LocalizableInteractionImpl.kt │ │ │ │ └── LocalizableReplyCallbackImpl.kt │ │ │ └── text │ │ │ │ ├── DefaultTextCommandLocaleProvider.kt │ │ │ │ ├── LocalizableTextCommandFactory.kt │ │ │ │ └── LocalizableTextCommandImpl.kt │ │ │ ├── modals │ │ │ ├── EphemeralModalHandlerData.kt │ │ │ ├── IModalHandlerData.kt │ │ │ ├── IPartialModalData.kt │ │ │ ├── InputData.kt │ │ │ ├── ModalBuilderImpl.kt │ │ │ ├── ModalDSL.kt │ │ │ ├── ModalData.kt │ │ │ ├── ModalHandlerContainer.kt │ │ │ ├── ModalHandlerInfo.kt │ │ │ ├── ModalListener.kt │ │ │ ├── ModalMaps.kt │ │ │ ├── ModalTimeoutInfo.kt │ │ │ ├── ModalsImpl.kt │ │ │ ├── PartialModalData.kt │ │ │ ├── PersistentModalHandlerData.kt │ │ │ ├── RequiresModalsChecker.kt │ │ │ ├── TextInputBuilderImpl.kt │ │ │ └── options │ │ │ │ ├── ModalHandlerDataOption.kt │ │ │ │ ├── ModalHandlerInputOption.kt │ │ │ │ ├── ModalHandlerOption.kt │ │ │ │ ├── ModalHandlerParameterImpl.kt │ │ │ │ └── builder │ │ │ │ ├── ModalHandlerDataOptionBuilderImpl.kt │ │ │ │ └── ModalHandlerInputOptionBuilderImpl.kt │ │ │ ├── options │ │ │ ├── CommandOptions.kt │ │ │ └── MethodParameters.kt │ │ │ ├── parameters │ │ │ ├── AggregatedParameterMixin.kt │ │ │ ├── AggregatorParameter.kt │ │ │ ├── CustomMethodOption.kt │ │ │ ├── MethodParameterMixin.kt │ │ │ ├── OptionParameter.kt │ │ │ ├── ParameterResolverAdapters.kt │ │ │ ├── ResolverContainer.kt │ │ │ ├── ServiceMethodOption.kt │ │ │ ├── SingleAggregatorParameter.kt │ │ │ ├── UserAggregatorParameter.kt │ │ │ ├── VarargAggregatorParameter.kt │ │ │ └── resolvers │ │ │ │ ├── AbstractUserSnowflakeResolver.kt │ │ │ │ ├── AttachmentResolver.kt │ │ │ │ ├── BooleanResolver.kt │ │ │ │ ├── ChannelResolverFactory.kt │ │ │ │ ├── DoubleResolver.kt │ │ │ │ ├── EmojiResolver.kt │ │ │ │ ├── GuildResolver.kt │ │ │ │ ├── IMentionableResolver.kt │ │ │ │ ├── InputUserResolver.kt │ │ │ │ ├── IntegerResolver.kt │ │ │ │ ├── LongResolver.kt │ │ │ │ ├── MemberResolver.kt │ │ │ │ ├── MentionsStringResolverFactory.kt │ │ │ │ ├── MessageResolver.kt │ │ │ │ ├── ResolverSupertypeChecker.kt │ │ │ │ ├── RoleResolver.kt │ │ │ │ ├── RoleResolverFactoryProvider.kt │ │ │ │ ├── StringResolver.kt │ │ │ │ ├── UserResolver.kt │ │ │ │ ├── UserSnowflakeResolver.kt │ │ │ │ ├── exceptions │ │ │ │ ├── MissingResolverAnnotation.kt │ │ │ │ ├── MissingResolverFactoryAnnotation.kt │ │ │ │ ├── MissingResolverFactorySuperclass.kt │ │ │ │ └── MissingResolverSuperclass.kt │ │ │ │ └── localization │ │ │ │ ├── LocalizationContextResolverFactories.kt │ │ │ │ └── LocalizationContextResolvers.kt │ │ │ └── utils │ │ │ ├── AnnotationUtils.kt │ │ │ ├── Checks.kt │ │ │ ├── Collections.kt │ │ │ ├── Exceptions.kt │ │ │ ├── ExecutionUtils.kt │ │ │ ├── FunctionFilter.kt │ │ │ ├── InternalJDAUtils.kt │ │ │ ├── InternalUtils.kt │ │ │ ├── LazyWritable.kt │ │ │ ├── LocalizationUtils.kt │ │ │ ├── References.kt │ │ │ ├── ReflectionMetadata.kt │ │ │ ├── ReflectionUtils.kt │ │ │ ├── Signatures.kt │ │ │ └── StackUtils.kt │ └── resources │ │ ├── META-INF │ │ ├── additional-spring-configuration-metadata.json │ │ ├── spring.factories │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ ├── bc_database_scripts │ │ ├── V3.0.0.2023.05.21__Create_database.sql │ │ ├── V3.0.0.2023.09.23__Component_rate_limit.sql │ │ ├── V3.0.0.2023.10.24__Component_filters.sql │ │ ├── V3.0.0.2024.05.08__Move_component_timeout.sql │ │ ├── V3.0.0.2024.08.24__Reset_timeout_on_use.sql │ │ ├── V3.0.0.2024.08.27__Application_commands_cache.sql │ │ ├── V3.0.0.2024.09.25__Component_rate_limit_reference.sql │ │ └── V3.0.0.2025.02.16__Component_data_serialization.sql │ │ └── bc_localization │ │ └── DefaultMessages-default.json └── test │ ├── README.md │ ├── java │ ├── doc │ │ └── java │ │ │ └── examples │ │ │ ├── commands │ │ │ └── slash │ │ │ │ ├── SlashSayAgainEphemeral.java │ │ │ │ ├── SlashSayAgainPersistent.java │ │ │ │ ├── SlashSelectRoleEphemeral.java │ │ │ │ ├── SlashSelectRolePersistent.java │ │ │ │ └── SlashSkip.java │ │ │ ├── filters │ │ │ ├── MyApplicationCommandFilter.java │ │ │ ├── MyComponentFilter.java │ │ │ └── MyTextCommandFilter.java │ │ │ ├── localization │ │ │ └── readers │ │ │ │ ├── LocalizationMapReaderProvider.java │ │ │ │ └── YamlLocalizationMapReader.java │ │ │ └── ratelimit │ │ │ ├── AnnotatedProxiedRateLimiterFactory.java │ │ │ └── ProxyManagerProvider.java │ └── io │ │ └── github │ │ └── freya022 │ │ └── botcommands │ │ └── test │ │ └── commands │ │ └── slash │ │ ├── SlashDIJava.java │ │ ├── SlashDbJava.java │ │ ├── SlashDynamicTypedResolverJava.java │ │ ├── SlashEmojis.java │ │ ├── SlashMyJavaCommand.java │ │ └── SlashSayJava.java │ ├── kotlin │ ├── doc │ │ └── kotlin │ │ │ └── examples │ │ │ ├── commands │ │ │ └── slash │ │ │ │ ├── SlashInMemoryRateLimit.kt │ │ │ │ ├── SlashPersistentRateLimit.kt │ │ │ │ ├── SlashSayAgainEphemeral.kt │ │ │ │ ├── SlashSayAgainPersistent.kt │ │ │ │ ├── SlashSelectRoleEphemeral.kt │ │ │ │ ├── SlashSelectRolePersistent.kt │ │ │ │ ├── SlashSkip.kt │ │ │ │ ├── SlashTypeSafeButtons.kt │ │ │ │ └── SlashTypeSafeSelectMenus.kt │ │ │ ├── filters │ │ │ ├── MyApplicationCommandFilter.kt │ │ │ ├── MyComponentFilter.kt │ │ │ └── MyTextCommandFilter.kt │ │ │ ├── localization │ │ │ └── readers │ │ │ │ ├── LocalizationMapReaderProvider.kt │ │ │ │ └── YamlLocalizationMapReader.kt │ │ │ ├── parameters │ │ │ └── MyCustomLocalizationResolverProvider.kt │ │ │ └── ratelimit │ │ │ └── ProxyManagerProvider.kt │ └── io │ │ └── github │ │ └── freya022 │ │ └── botcommands │ │ ├── framework │ │ ├── AppEmojisTest.kt │ │ ├── ComponentTests.kt │ │ ├── CustomConditionTests.kt │ │ ├── FakeBot.kt │ │ ├── H2MigrationTests.kt │ │ ├── RecursiveAnnotationTests.kt │ │ ├── ResolverCheckTests.kt │ │ ├── TestH2.kt │ │ └── utils │ │ │ └── Utils.kt │ │ ├── othertests │ │ ├── CallableReferenceTest.kt │ │ ├── CollectionTypeTest.kt │ │ ├── EmojiUtilsTest.kt │ │ ├── FactoryTypeTest.kt │ │ ├── FunctionTypeTest.kt │ │ ├── InternalTest.kt │ │ ├── JsonDiffTest.kt │ │ ├── KotlinTypeTokenTest.kt │ │ ├── ObjectTest.kt │ │ └── RestResultTest.kt │ │ ├── spring │ │ └── test │ │ │ └── SpringMain.kt │ │ └── test │ │ ├── CoroutineEventManagerSupplier.kt │ │ ├── CustomObject.kt │ │ ├── Main.kt │ │ ├── MyAutocompleteTransformer.kt │ │ ├── MyGlobalExceptionHandler.kt │ │ ├── MyHelpBuilderConsumer.kt │ │ ├── MyTextPrefixSupplier.kt │ │ ├── VersionTest.kt │ │ ├── commands │ │ ├── message │ │ │ ├── MessageContextAddReactionRole.kt │ │ │ ├── MessageContextDeleteIncluding.kt │ │ │ ├── MessageContextEmbedLink.kt │ │ │ ├── MessageContextGetJson.kt │ │ │ ├── MessageContextRaw.kt │ │ │ └── MessageContextTest.kt │ │ ├── slash │ │ │ ├── SlashAggregate.kt │ │ │ ├── SlashBanManual.kt │ │ │ ├── SlashBasicAutocomplete.kt │ │ │ ├── SlashComponentData.kt │ │ │ ├── SlashCooldown.kt │ │ │ ├── SlashDI.kt │ │ │ ├── SlashDb.kt │ │ │ ├── SlashDeclarationFilter.kt │ │ │ ├── SlashDeletedButton.kt │ │ │ ├── SlashDynamicTypedResolver.kt │ │ │ ├── SlashEventWaiter.kt │ │ │ ├── SlashFilter.kt │ │ │ ├── SlashForumTest.kt │ │ │ ├── SlashGenerateComponents.kt │ │ │ ├── SlashGroupTest.kt │ │ │ ├── SlashInlineClassVararg.kt │ │ │ ├── SlashInteractionMetadata.kt │ │ │ ├── SlashLength.kt │ │ │ ├── SlashLocalization.kt │ │ │ ├── SlashMentionsString.kt │ │ │ ├── SlashModal.kt │ │ │ ├── SlashMyCommand.kt │ │ │ ├── SlashNewButtons.kt │ │ │ ├── SlashNewSelects.kt │ │ │ ├── SlashNsfw.kt │ │ │ ├── SlashPagination.kt │ │ │ ├── SlashPermissions.kt │ │ │ ├── SlashRateLimit.kt │ │ │ ├── SlashResolveMentions.kt │ │ │ ├── SlashSay.kt │ │ │ ├── SlashServiceOption.kt │ │ │ ├── SlashSubWithGroup.kt │ │ │ ├── SlashTest.kt │ │ │ ├── SlashThreadById.kt │ │ │ ├── SlashTimeUnit.kt │ │ │ ├── SlashUploadStream.kt │ │ │ ├── SlashVararg.kt │ │ │ ├── SlashVoiceState.kt │ │ │ ├── StateExample.kt │ │ │ └── userapps │ │ │ │ ├── SlashDetachedPermissions.kt │ │ │ │ ├── SlashEntity.kt │ │ │ │ ├── SlashIntegrationContexts.kt │ │ │ │ ├── SlashIntegrationOwners.kt │ │ │ │ ├── SlashMaxFollowupTest.kt │ │ │ │ ├── SlashPrivateChannelInBot.kt │ │ │ │ └── SlashStealChannel.kt │ │ ├── text │ │ │ ├── MyHelpCommand.kt │ │ │ ├── TextAttachmentParameters.kt │ │ │ ├── TextDelay.kt │ │ │ ├── TextException.kt │ │ │ ├── TextFilter.kt │ │ │ ├── TextHelpTesting.kt │ │ │ ├── TextLocalization.kt │ │ │ ├── TextMentionable.kt │ │ │ ├── TextTest.kt │ │ │ └── TextVararg.kt │ │ └── user │ │ │ ├── UserContextInfo.kt │ │ │ └── UserContextTest.kt │ │ ├── config │ │ ├── Config.kt │ │ ├── Data.kt │ │ ├── Environment.kt │ │ └── db │ │ │ ├── H2DatabaseSource.kt │ │ │ └── PostgresDatabaseSource.kt │ │ ├── filters │ │ └── ComplexFilter.kt │ │ ├── listeners │ │ ├── DisabledTextListener.kt │ │ └── RequiredIntentsTextListener.kt │ │ ├── readme │ │ ├── SlashBan.kt │ │ └── TextBan.kt │ │ ├── resolvers │ │ ├── CustomObjectResolver.kt │ │ ├── EnumResolvers.kt │ │ ├── ListResolver.kt │ │ ├── MapResolver.kt │ │ └── UserResolver.kt │ │ ├── services │ │ ├── Bot.kt │ │ ├── ConditionalServiceTest.kt │ │ ├── Disabled.kt │ │ ├── DisabledFactoriesByClass.kt │ │ ├── FactoryServiceTest.kt │ │ ├── MyDevService.kt │ │ ├── NamedService.kt │ │ ├── NonUniqueCommandFactoryTest.kt │ │ ├── NonUniqueProviderTest.kt │ │ ├── Profile.kt │ │ ├── ProfileChecker.kt │ │ ├── UnusedInterfacedService.kt │ │ └── annotations │ │ │ └── RequireProfile.kt │ │ ├── switches │ │ ├── TestDatabase.kt │ │ ├── TestLanguage.kt │ │ └── TestService.kt │ │ └── utils │ │ └── JDA.kt │ └── resources │ ├── application.properties │ ├── bc_localization │ ├── DefaultMessages.json │ ├── DefaultMessages_fr.json │ ├── MyCommands.json │ ├── MyCommands_en_GB.json │ ├── MyCommands_en_US.json │ ├── MyCommands_fr.json │ ├── Test.json │ ├── Test_de.json │ ├── Test_en.json │ ├── Test_en_US.json │ └── Test_fr.json │ ├── bc_test_database_scripts │ └── V3.0.0.2024.09.24__Persistent_bucket_state.sql │ ├── commands_data │ ├── add_option_in_subcommand │ │ ├── new.json │ │ └── old.json │ ├── diff_command_description │ │ ├── new.json │ │ └── old.json │ ├── diff_command_order │ │ ├── new.json │ │ └── old.json │ └── diff_option_order │ │ ├── new.json │ │ └── old.json │ └── emojis │ ├── kotlin.png │ └── kotlin2.png └── test-files ├── examples └── config-template │ ├── config.json │ ├── logback-test.xml │ └── logback.xml └── test └── config-template ├── config.json ├── logback-test.xml └── logback.xml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: freya022 2 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | ## Support 2 | Don't hesitate to join [the support server](https://discord.gg/frpCcQfvTz) if you have any question! -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /.idea/workspace.xml 3 | 4 | *.iml 5 | .idea 6 | target 7 | release.properties 8 | pom.xml.releaseBackup 9 | 10 | schemas/Test.json 11 | /schemas 12 | dev-config 13 | dev-data -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freya022/BotCommands/8f6ae7b041a1f343e8bd289b95ff764734c5cae6/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /BotCommands 3.X Live Templates.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freya022/BotCommands/8f6ae7b041a1f343e8bd289b95ff764734c5cae6/BotCommands 3.X Live Templates.zip -------------------------------------------------------------------------------- /assets/command_help_embed_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freya022/BotCommands/8f6ae7b041a1f343e8bd289b95ff764734c5cae6/assets/command_help_embed_example.png -------------------------------------------------------------------------------- /assets/slash_ban_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freya022/BotCommands/8f6ae7b041a1f343e8bd289b95ff764734c5cae6/assets/slash_ban_example.gif -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - sdk install java 17.0.7-tem 3 | - sdk use java 17.0.7-tem -------------------------------------------------------------------------------- /src/examples/kotlin/io/github/freya022/bot/CoroutineEventManagerSupplier.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.bot 2 | 3 | import dev.minn.jda.ktx.events.CoroutineEventManager 4 | import io.github.freya022.botcommands.api.core.ICoroutineEventManagerSupplier 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import io.github.freya022.botcommands.api.core.utils.namedDefaultScope 7 | 8 | @BService 9 | object CoroutineEventManagerSupplier : ICoroutineEventManagerSupplier { 10 | override fun get(): CoroutineEventManager { 11 | val scope = namedDefaultScope("$botName Coroutine", 4) 12 | return CoroutineEventManager(scope) 13 | } 14 | } -------------------------------------------------------------------------------- /src/examples/kotlin/io/github/freya022/bot/commands/text/HelpCommand.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.bot.commands.text 2 | 3 | import io.github.freya022.botcommands.api.commands.text.BaseCommandEvent 4 | import io.github.freya022.botcommands.api.commands.text.IHelpCommand 5 | import io.github.freya022.botcommands.api.commands.text.TextCommandInfo 6 | import io.github.freya022.botcommands.api.core.service.annotations.BService 7 | 8 | @BService 9 | class HelpCommand : IHelpCommand { 10 | override fun onInvalidCommand(event: BaseCommandEvent, commandInfo: TextCommandInfo) { 11 | event.respond("Invalid command syntax !").queue() 12 | } 13 | } -------------------------------------------------------------------------------- /src/examples/kotlin/io/github/freya022/bot/commands/text/TextNumber.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.bot.commands.text 2 | 3 | import io.github.freya022.botcommands.api.commands.annotations.Command 4 | import io.github.freya022.botcommands.api.commands.text.BaseCommandEvent 5 | import io.github.freya022.botcommands.api.commands.text.TextCommand 6 | import io.github.freya022.botcommands.api.commands.text.annotations.JDATextCommandVariation 7 | import io.github.freya022.botcommands.api.commands.text.annotations.TextOption 8 | import kotlin.math.PI 9 | 10 | @Command 11 | class TextNumber : TextCommand() { 12 | @JDATextCommandVariation(path = ["number"]) 13 | fun onTextNumber(event: BaseCommandEvent, @TextOption number: Int) { 14 | event.reply("$number * pi = ${number * PI}").queue() 15 | } 16 | } -------------------------------------------------------------------------------- /src/examples/kotlin/io/github/freya022/bot/config/Data.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.bot.config 2 | 3 | import java.io.FileNotFoundException 4 | import java.nio.file.Path 5 | import kotlin.io.path.absolutePathString 6 | import kotlin.io.path.notExists 7 | 8 | object Data { 9 | /** 10 | * Where your bot can write data if needed 11 | */ 12 | val folder: Path = Environment.folder.resolve(if (Environment.isDev) "dev-data" else "data") 13 | 14 | /** 15 | * Checks whether the path exists, throwing if not. 16 | */ 17 | private fun Path.validatedPath(desc: String): Path = this.also { 18 | if (it.notExists()) 19 | throw FileNotFoundException("$desc at ${it.absolutePathString()} does not exist.") 20 | } 21 | } -------------------------------------------------------------------------------- /src/examples/kotlin/io/github/freya022/bot/config/Environment.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.bot.config 2 | 3 | import java.nio.file.Path 4 | import kotlin.io.path.Path 5 | import kotlin.io.path.exists 6 | 7 | object Environment { 8 | /** 9 | * The folder where the data and configuration directories reside. 10 | */ 11 | val folder: Path = Path("test-files", "examples") 12 | 13 | /** 14 | * The mode is determined by checking if the 15 | * `dev-config` directory exists in the current directory. 16 | */ 17 | val isDev: Boolean = folder.resolve("dev-config").exists() 18 | 19 | val configFolder: Path = 20 | folder.resolve(if (isDev) "dev-config" else "config") 21 | val logbackConfigPath: Path = configFolder.resolve(if (isDev) "logback-test.xml" else "logback.xml") 22 | } -------------------------------------------------------------------------------- /src/examples/resources/bc_localization/Commands.json: -------------------------------------------------------------------------------- 1 | { 2 | // --8<-- [start:default_description-json] 3 | "say_default_description": { 4 | "description": "Says something", 5 | "options": { 6 | "content.description": "What to say" 7 | } 8 | } 9 | // --8<-- [end:default_description-json] 10 | , 11 | "ban": { 12 | "outputs": { 13 | "defaultReason": "No reason supplied", 14 | "confirmationMessage": "Do you really want to ban {userMention}?", 15 | "timeout": "Timeout", 16 | "success": "{userMention} has been banned, {time} {unit} of messages were deleted, reason: '{reason}'", 17 | "cancelled": "The ban has been cancelled" 18 | }, 19 | "errors": { 20 | "bot.interactError": "I can't ban {userMention}", 21 | "user.interactError": "You cannot ban {userMention}" 22 | }, 23 | "buttons": { 24 | "cancel": "Cancel", 25 | "confirm": "Confirm" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/commands/application/ApplicationGeneratedValueSupplier.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application; 2 | 3 | import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | @FunctionalInterface 8 | public interface ApplicationGeneratedValueSupplier { 9 | @Nullable 10 | Object getDefaultValue(@NotNull CommandInteractionPayload event); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/commands/text/TextGeneratedValueSupplier.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | @FunctionalInterface 7 | public interface TextGeneratedValueSupplier { 8 | @Nullable 9 | Object getDefaultValue(@NotNull BaseCommandEvent event); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/commands/text/exceptions/BadIdException.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.exceptions; 2 | 3 | public class BadIdException extends Exception { 4 | public BadIdException() { 5 | super("Not an IMentionable ID", null, true, false); 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/commands/text/exceptions/NoIdException.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.exceptions; 2 | 3 | public class NoIdException extends Exception { 4 | public NoIdException() { 5 | super("No supplied IMentionable", null, true, false); 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/core/db/StatementFunction.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.db; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.sql.SQLException; 6 | 7 | /** 8 | * Functional interface for Java JDBC prepared statements. 9 | * 10 | * @param Type of the returned object 11 | * @param Type of the exception thrown 12 | * 13 | * @see BlockingDatabase#withStatement(String, boolean, StatementFunction) 14 | */ 15 | @FunctionalInterface 16 | public interface StatementFunction { 17 | R apply(@NotNull BlockingPreparedStatement statement) throws SQLException, E; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/core/db/TransactionFunction.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.db; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.sql.SQLException; 6 | 7 | /** 8 | * Functional interface for Java JDBC transactions. 9 | * 10 | * @param Type of the returned object 11 | * @param Type of the exception thrown 12 | * 13 | * @see BlockingDatabase#withTransaction(boolean, TransactionFunction) 14 | */ 15 | @FunctionalInterface 16 | public interface TransactionFunction { 17 | R apply(@NotNull BlockingTransaction transaction) throws SQLException, E; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/localization/LocalizationMapRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.Locale; 6 | 7 | public record LocalizationMapRequest(@NotNull String baseName, @NotNull Locale requestedLocale, 8 | @NotNull String bundleName) { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/utils/RichTextConsumer.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.utils; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | @FunctionalInterface 7 | public interface RichTextConsumer { 8 | void consume(String substring, RichTextType type); 9 | } -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/api/utils/RichTextType.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.utils; 2 | 3 | import net.dv8tion.jda.api.entities.Message.MentionType; 4 | 5 | import java.util.regex.Pattern; 6 | 7 | public enum RichTextType { 8 | USER(MentionType.USER), 9 | EMOJI(MentionType.EMOJI), 10 | CHANNEL(MentionType.CHANNEL), 11 | ROLE(MentionType.ROLE), 12 | EVERYONE(MentionType.EVERYONE), 13 | HERE(MentionType.HERE), 14 | UNICODE_EMOTE(null), 15 | URL(null), 16 | TEXT(null); 17 | 18 | private final MentionType mentionType; 19 | 20 | RichTextType(MentionType mentionType) { 21 | this.mentionType = mentionType; 22 | } 23 | 24 | public MentionType getMentionType() { 25 | return mentionType; 26 | } 27 | 28 | public Pattern getPattern() { 29 | return mentionType.getPattern(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/github/freya022/botcommands/internal/utils/TimeoutExceptionAccessor.java: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.utils; 2 | 3 | import kotlinx.coroutines.TimeoutCancellationException; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class TimeoutExceptionAccessor { 7 | @NotNull 8 | public static TimeoutCancellationException createComponentTimeoutException() { 9 | return new TimeoutCancellationException("Timed out waiting for component"); 10 | } 11 | 12 | @NotNull 13 | public static TimeoutCancellationException createModalTimeoutException() { 14 | return new TimeoutCancellationException("Timed out waiting for modal"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/ReceiverConsumer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api 2 | 3 | fun interface ReceiverConsumer : (T) -> Unit { 4 | fun T.accept() 5 | 6 | override fun invoke(p1: T) { 7 | with(p1) { accept() } 8 | } 9 | 10 | fun applyTo(receiver: T): T { 11 | with(this) { receiver.accept() } 12 | 13 | return receiver 14 | } 15 | 16 | companion object { 17 | private val NOOP = ReceiverConsumer { } 18 | 19 | @Suppress("UNCHECKED_CAST") 20 | fun noop(): ReceiverConsumer = NOOP as ReceiverConsumer 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/annotations/CommandMarker.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.annotations 2 | 3 | /** 4 | * Simple marker annotation to enable you to suppress unused warnings. 5 | * 6 | * IDEs such as IntelliJ will suggest you a quick-fix to ignore unused warnings if annotated with `@CommandMarker`. 7 | */ 8 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 9 | @Retention(AnnotationRetention.SOURCE) 10 | annotation class CommandMarker -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/CommandInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.core.IDeclarationSiteHolder 5 | import net.dv8tion.jda.api.Permission 6 | import java.util.* 7 | 8 | /** 9 | * Represents a text/application command. 10 | */ 11 | interface CommandInfo : INamedCommand, IDeclarationSiteHolder, IRateLimitHolder { 12 | /** 13 | * The main context. 14 | */ 15 | val context: BContext 16 | 17 | /** 18 | * The permissions required for the caller to use this command. 19 | */ 20 | val userPermissions: EnumSet 21 | 22 | /** 23 | * The permissions required for the bot to run this command. 24 | */ 25 | val botPermissions: EnumSet 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/CommandType.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | enum class CommandType { 4 | TEXT, 5 | SLASH, 6 | MESSAGE_CONTEXT, 7 | USER_CONTEXT 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/ICommandOptionContainer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | import io.github.freya022.botcommands.api.commands.options.CommandOption 4 | import io.github.freya022.botcommands.api.core.Executable 5 | 6 | /** 7 | * Holds Discord input options. 8 | */ 9 | interface ICommandOptionContainer : Executable { 10 | /** 11 | * All options representing a Discord input. 12 | */ 13 | val discordOptions: List 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/ICommandParameterContainer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | import io.github.freya022.botcommands.api.core.Executable 4 | 5 | /** 6 | * Holds parameters of commands. 7 | */ 8 | interface ICommandParameterContainer : Executable { 9 | 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/IFilterContainer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | /** 4 | * May hold filters. 5 | */ 6 | interface IFilterContainer { 7 | /** 8 | * Return `true` if this has a one or more filters. 9 | */ 10 | fun hasFilters(): Boolean 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/INamedCommand.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | /** 4 | * A command with a name and possibly a parent. 5 | */ 6 | interface INamedCommand { 7 | /** 8 | * The parent of this command, `null` for top-level commands. 9 | */ 10 | val parentInstance: INamedCommand? 11 | 12 | /** 13 | * The name of this command. 14 | * 15 | * Does not include the names of its parents. 16 | */ 17 | val name: String 18 | 19 | /** 20 | * The complete path that leads to this command. 21 | */ 22 | val path: CommandPath 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/IRateLimitHolder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands 2 | 3 | /** 4 | * Holds a rate limiter. 5 | */ 6 | interface IRateLimitHolder { 7 | /** 8 | * Return `true` if this has a rate limiter. 9 | */ 10 | fun hasRateLimiter(): Boolean 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/annotations/BotPermissions.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.annotations 2 | 3 | import net.dv8tion.jda.api.Permission 4 | 5 | /** 6 | * Sets the required bot permissions to use this text / application command. 7 | * 8 | * **Text commands note:** This applies to the command itself, not only this variation, 9 | * in other words, this applies to all commands with the same path. 10 | */ 11 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS) 12 | @Retention(AnnotationRetention.RUNTIME) 13 | annotation class BotPermissions(@get:JvmName("value") vararg val permissions: Permission) 14 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/annotations/UserPermissions.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.annotations 2 | 3 | import net.dv8tion.jda.api.Permission 4 | 5 | /** 6 | * Sets the required user permissions to use this text / application command. 7 | * 8 | * **Text commands note:** This applies to the command itself, not only this variation, 9 | * in other words, this applies to all commands with the same path. 10 | */ 11 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS) 12 | @Retention(AnnotationRetention.RUNTIME) 13 | annotation class UserPermissions(@get:JvmName("value") vararg val permissions: Permission) 14 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/CommandUpdateException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application 2 | 3 | import io.github.freya022.botcommands.internal.utils.shortSignature 4 | import kotlin.reflect.KFunction 5 | 6 | /** 7 | * Simple wrapper for the failing command declaration function and its exception 8 | * 9 | * @see CommandUpdateResult 10 | */ 11 | class CommandUpdateException internal constructor(val function: KFunction, val throwable: Throwable) { 12 | override fun toString(): String = "$throwable at: ${function.shortSignature}" 13 | } 14 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/LengthRange.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application 2 | 3 | import net.dv8tion.jda.api.interactions.commands.build.OptionData 4 | 5 | class LengthRange private constructor(val min: Int, val max: Int) { 6 | init { 7 | require(min > 0) { 8 | "String length must be positive" 9 | } 10 | require(max <= OptionData.MAX_STRING_OPTION_LENGTH) { 11 | "Cannot have a string length higher than ${OptionData.MAX_STRING_OPTION_LENGTH}" 12 | } 13 | } 14 | 15 | companion object { 16 | @JvmStatic 17 | fun of(min: Int, max: Int) = LengthRange(min, max) 18 | 19 | infix fun Int.range(maxLength: Int) = LengthRange(this, maxLength) 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/ValueRange.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application 2 | 3 | class ValueRange private constructor(val min: Number, val max: Number) { 4 | companion object { 5 | @JvmStatic 6 | fun ofLong(minValue: Long, maxValue: Long) = 7 | ValueRange(minValue, maxValue) 8 | 9 | @JvmStatic 10 | fun ofDouble(minValue: Double, maxValue: Double) = 11 | ValueRange(minValue, maxValue) 12 | 13 | infix fun Long.range(maxValue: Long) = ValueRange(this, maxValue) 14 | 15 | infix fun Int.range(maxValue: Int) = ValueRange(this, maxValue) 16 | 17 | infix fun Double.range(maxValue: Double) = ValueRange(this, maxValue) 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/annotations/CommandId.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.annotations.TopLevelSlashCommandData 4 | 5 | /** 6 | * Sets a **unique** command ID on an **annotated** application command function. 7 | * 8 | * **Note:** This only applies to top-level commands, for slash commands, 9 | * this means the annotation needs to be used alongside [@TopLevelSlashCommandData][TopLevelSlashCommandData]. 10 | * 11 | * @see DeclarationFilter @DeclarationFilter 12 | */ 13 | @Target(AnnotationTarget.FUNCTION) 14 | @Retention(AnnotationRetention.RUNTIME) 15 | annotation class CommandId(val value: String) 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/annotations/ContextOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.annotations.Optional 4 | import io.github.freya022.botcommands.api.commands.application.context.message.builder.MessageCommandBuilder 5 | import io.github.freya022.botcommands.api.commands.application.context.user.builder.UserCommandBuilder 6 | import org.jetbrains.annotations.Nullable 7 | 8 | /** 9 | * Sets a parameter as a context command option. 10 | * 11 | * @see Optional @Optional 12 | * 13 | * @see Nullable @Nullable 14 | * @see UserCommandBuilder.option DSL equivalent (user context commands) 15 | * @see MessageCommandBuilder.option DSL equivalent (message context commands) 16 | */ 17 | @Target(AnnotationTarget.VALUE_PARAMETER) 18 | @Retention(AnnotationRetention.RUNTIME) 19 | annotation class ContextOption 20 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/message/builder/MessageCommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.message.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.builder.TopLevelApplicationCommandBuilder 4 | import io.github.freya022.botcommands.api.commands.application.context.message.options.builder.MessageCommandOptionAggregateBuilder 5 | import io.github.freya022.botcommands.api.commands.application.context.message.options.builder.MessageCommandOptionRegistry 6 | 7 | interface MessageCommandBuilder : TopLevelApplicationCommandBuilder, 8 | MessageCommandOptionRegistry 9 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/message/options/MessageContextCommandOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.message.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.options.ContextCommandOption 4 | 5 | /** 6 | * Represents a Discord input option of a message context command. 7 | */ 8 | interface MessageContextCommandOption : ContextCommandOption { 9 | 10 | override val executable get() = parent.executable 11 | override val parent: MessageContextCommandParameter 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/message/options/MessageContextCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.message.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.message.MessageCommandInfo 4 | import io.github.freya022.botcommands.api.commands.application.context.options.ContextCommandParameter 5 | 6 | /** 7 | * Represents a message context command parameter, 8 | * which has its value computed by an aggregation function, from one or more options. 9 | */ 10 | interface MessageContextCommandParameter : ContextCommandParameter { 11 | override val nestedAggregatedParameters: List 12 | 13 | override val executable: MessageCommandInfo 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/message/options/builder/MessageCommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.message.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionAggregateBuilder 4 | 5 | interface MessageCommandOptionAggregateBuilder : 6 | ApplicationCommandOptionAggregateBuilder, 7 | MessageCommandOptionRegistry 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/message/options/builder/MessageCommandOptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.message.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionBuilder 4 | 5 | interface MessageCommandOptionBuilder : ApplicationCommandOptionBuilder 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/options/ContextCommandOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.ApplicationCommandOption 4 | 5 | /** 6 | * Represents a Discord input option of an application context command. 7 | */ 8 | interface ContextCommandOption : ApplicationCommandOption -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/options/ContextCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.ApplicationCommandParameter 4 | 5 | /** 6 | * Represents a context command parameter, 7 | * which has its value computed by an aggregation function, from one or more options. 8 | */ 9 | interface ContextCommandParameter : ApplicationCommandParameter -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/user/builder/UserCommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.user.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.builder.TopLevelApplicationCommandBuilder 4 | import io.github.freya022.botcommands.api.commands.application.context.user.options.builder.UserCommandOptionAggregateBuilder 5 | import io.github.freya022.botcommands.api.commands.application.context.user.options.builder.UserCommandOptionRegistry 6 | 7 | interface UserCommandBuilder : TopLevelApplicationCommandBuilder, 8 | UserCommandOptionRegistry 9 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/user/options/UserContextCommandOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.user.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.options.ContextCommandOption 4 | 5 | /** 6 | * Represents a Discord input option of a user context command. 7 | */ 8 | interface UserContextCommandOption : ContextCommandOption { 9 | 10 | override val executable get() = parent.executable 11 | override val parent: UserContextCommandParameter 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/user/options/UserContextCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.user.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.options.ContextCommandParameter 4 | import io.github.freya022.botcommands.api.commands.application.context.user.UserCommandInfo 5 | 6 | /** 7 | * Represents a user context command parameter, 8 | * which has its value computed by an aggregation function, from one or more options. 9 | */ 10 | interface UserContextCommandParameter : ContextCommandParameter { 11 | override val nestedAggregatedParameters: List 12 | 13 | override val executable: UserCommandInfo 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/user/options/builder/UserCommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.user.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionAggregateBuilder 4 | 5 | interface UserCommandOptionAggregateBuilder : 6 | ApplicationCommandOptionAggregateBuilder, 7 | UserCommandOptionRegistry 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/context/user/options/builder/UserCommandOptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.context.user.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionBuilder 4 | 5 | interface UserCommandOptionBuilder : ApplicationCommandOptionBuilder 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/diff/DiffEngine.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.diff 2 | 3 | import io.github.freya022.botcommands.api.core.config.application.cache.ApplicationCommandsCacheConfig 4 | import io.github.freya022.botcommands.internal.commands.application.diff.ApplicationCommandDiffEngine 5 | import io.github.freya022.botcommands.internal.commands.application.diff.NewApplicationCommandDiffEngine 6 | 7 | /** 8 | * Represents predefined implementation of an application command diff engine. 9 | * 10 | * @see ApplicationCommandsCacheConfig.diffEngine 11 | */ 12 | enum class DiffEngine(@get:JvmSynthetic internal val instance: ApplicationCommandDiffEngine) { 13 | /** 14 | * Cleaner logs with what exactly changed. 15 | */ 16 | NEW(NewApplicationCommandDiffEngine) 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/exceptions/ApplicationCommandUpdateException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.exceptions 2 | 3 | /** 4 | * An exception thrown when pushing commands to Discord. 5 | */ 6 | class ApplicationCommandUpdateException internal constructor( 7 | message: String, 8 | cause: Throwable, 9 | ) : RuntimeException(message, cause) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/options/ApplicationCommandOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.options 2 | 3 | import io.github.freya022.botcommands.api.commands.options.CommandOption 4 | 5 | /** 6 | * Represents a Discord input option of an application command. 7 | */ 8 | interface ApplicationCommandOption : CommandOption { 9 | 10 | override val executable get() = parent.executable 11 | override val parent: ApplicationCommandParameter 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/options/ApplicationCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.ApplicationCommandInfo 4 | import io.github.freya022.botcommands.api.commands.options.CommandParameter 5 | 6 | /** 7 | * Represents an application command parameter, 8 | * which has its value computed by an aggregation function, from one or more options. 9 | */ 10 | interface ApplicationCommandParameter : CommandParameter { 11 | override val nestedAggregatedParameters: List 12 | 13 | override val executable: ApplicationCommandInfo 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/options/builder/ApplicationCommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.options.builder.CommandOptionAggregateBuilder 4 | 5 | interface ApplicationCommandOptionAggregateBuilder : CommandOptionAggregateBuilder, 6 | ApplicationOptionRegistry where T : ApplicationCommandOptionAggregateBuilder 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/options/builder/ApplicationCommandOptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.options.builder.CommandOptionBuilder 4 | 5 | interface ApplicationCommandOptionBuilder : CommandOptionBuilder 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/SlashSubcommandGroupInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash 2 | 3 | import io.github.freya022.botcommands.api.commands.INamedCommand 4 | import io.github.freya022.botcommands.api.core.IDeclarationSiteHolder 5 | 6 | /** 7 | * Represents a slash subcommand group. 8 | */ 9 | interface SlashSubcommandGroupInfo : INamedCommand, IDeclarationSiteHolder { 10 | /** 11 | * The description of this slash command group. 12 | * 13 | * May have been set manually or come from a **root** localization bundle. 14 | */ 15 | val description: String 16 | 17 | /** 18 | * Subcommands of this top-level slash command, the key is the name of the subcommand. 19 | */ 20 | val subcommands: Map 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/SlashSubcommandInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash 2 | 3 | /** 4 | * Represents a slash subcommand, 5 | * either in a [top-level command][TopLevelSlashCommandInfo], 6 | * or a [subcommand group][SlashSubcommandGroupInfo]. 7 | */ 8 | interface SlashSubcommandInfo : SlashCommandInfo -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/annotations/ChannelTypes.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.annotations 2 | 3 | import net.dv8tion.jda.api.entities.channel.ChannelType 4 | import net.dv8tion.jda.api.entities.channel.concrete.TextChannel 5 | 6 | /** 7 | * Sets the desired channel types for this parameter. 8 | * 9 | * This works for annotated commands as well as code-declared commands 10 | * 11 | * You can alternatively use a specific channel type, 12 | * such as [TextChannel] to automatically restrict the channel type. 13 | * 14 | * ### Merging 15 | * This annotation can be merged if found with other meta-annotations. 16 | * Keep in mind that a *direct* annotation overrides all meta-annotations. 17 | */ 18 | @Target(AnnotationTarget.VALUE_PARAMETER) 19 | @Retention(AnnotationRetention.RUNTIME) 20 | annotation class ChannelTypes(vararg val value: ChannelType) 21 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/annotations/DoubleRange.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.options.builder.SlashCommandOptionBuilder 4 | 5 | /** 6 | * Sets the minimum and maximum values on the specified [@SlashOption][SlashOption]. 7 | * 8 | * **Note:** This is only for floating point number types! 9 | * 10 | * @see SlashCommandOptionBuilder.valueRange DSL equivalent 11 | */ 12 | @Target(AnnotationTarget.VALUE_PARAMETER) 13 | @Retention(AnnotationRetention.RUNTIME) 14 | annotation class DoubleRange( 15 | /** 16 | * The minimum value of this parameter (included) 17 | */ 18 | val from: Double, 19 | 20 | /** 21 | * The maximum value of this parameter (included) 22 | */ 23 | val to: Double 24 | ) 25 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/annotations/LongRange.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.options.builder.SlashCommandOptionBuilder 4 | 5 | /** 6 | * Sets the minimum and maximum values on the specified [@SlashOption][SlashOption]. 7 | * 8 | * **Note:** This is only for integer types! 9 | * 10 | * @see SlashCommandOptionBuilder.valueRange DSL equivalent 11 | */ 12 | @Target(AnnotationTarget.VALUE_PARAMETER) 13 | @Retention(AnnotationRetention.RUNTIME) 14 | annotation class LongRange( 15 | /** 16 | * The minimum value of this parameter (included) 17 | */ 18 | val from: Long, 19 | 20 | /** 21 | * The maximum value of this parameter (included) 22 | */ 23 | val to: Long 24 | ) 25 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/autocomplete/AutocompleteMode.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.autocomplete 2 | 3 | /** 4 | * See values 5 | */ 6 | enum class AutocompleteMode { 7 | /** 8 | * Sorts the strings by fuzzy search score 9 | * 10 | * This shows the most relevant results most of the time, regardless of if the user did a few mistakes when typing 11 | * 12 | * @see AutocompleteAlgorithms.fuzzyMatching 13 | */ 14 | FUZZY, 15 | 16 | /** 17 | * Sorts the strings by the smallest string that also starts with the user query 18 | * 19 | * Might be useful for when exact names are needed 20 | * 21 | * @see AutocompleteAlgorithms.fuzzyMatchingWithContinuity 22 | */ 23 | CONTINUITY 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/autocomplete/ToStringFunction.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.autocomplete 2 | 3 | fun interface ToStringFunction { 4 | fun toString(item: T): String 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/builder/SlashSubcommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.builder 2 | 3 | interface SlashSubcommandBuilder : SlashCommandBuilder 4 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/options/SlashCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.ApplicationCommandParameter 4 | import io.github.freya022.botcommands.api.commands.application.slash.SlashCommandInfo 5 | 6 | /** 7 | * Represents a slash command parameter, 8 | * which has its value computed by an aggregation function, from one or more options. 9 | */ 10 | interface SlashCommandParameter : ApplicationCommandParameter { 11 | override val nestedAggregatedParameters: List 12 | 13 | override val executable: SlashCommandInfo 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/application/slash/options/builder/SlashCommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.application.slash.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionAggregateBuilder 4 | 5 | interface SlashCommandOptionAggregateBuilder : ApplicationCommandOptionAggregateBuilder, 6 | SlashOptionRegistry 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/builder/ExecutableCommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilder 4 | import io.github.freya022.botcommands.api.core.options.builder.OptionRegistry 5 | 6 | interface ExecutableCommandBuilder> : CommandBuilder, 7 | OptionRegistry 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/builder/RateLimitBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.ratelimit.RateLimiter 4 | import io.github.freya022.botcommands.api.commands.ratelimit.declaration.RateLimitManager 5 | import io.github.freya022.botcommands.api.core.IDeclarationSiteHolderBuilder 6 | import io.github.freya022.botcommands.internal.commands.CommandDSL 7 | 8 | /** 9 | * Builder interface for rate limits. 10 | * 11 | * You can set a declaration site different from the default location (where the rate limit was created in the code) here. 12 | * 13 | * @see CommandBuilder.rateLimit 14 | * @see RateLimitManager.rateLimit 15 | */ 16 | @CommandDSL 17 | interface RateLimitBuilder : IDeclarationSiteHolderBuilder { 18 | val group: String 19 | val rateLimiter: RateLimiter 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/options/CommandOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.options 2 | 3 | import io.github.freya022.botcommands.api.core.options.Option 4 | 5 | /** 6 | * Represents a Discord input of a command. 7 | */ 8 | interface CommandOption : Option { 9 | 10 | override val parent: CommandParameter 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/options/CommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.options 2 | 3 | import io.github.freya022.botcommands.api.parameters.AggregatedParameter 4 | 5 | /** 6 | * Represents a command parameter, 7 | * which has its value computed by an aggregation function, from one or more options. 8 | */ 9 | interface CommandParameter : AggregatedParameter -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/options/builder/CommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.options.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilder 4 | 5 | interface CommandOptionAggregateBuilder> : OptionAggregateBuilder 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/options/builder/CommandOptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.options.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionBuilder 4 | 5 | interface CommandOptionBuilder : OptionBuilder 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/CancellableRateLimit.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.ratelimit 2 | 3 | /** 4 | * Allows cancellation of rate limits by refilling tokens, usually delegated on events. 5 | */ 6 | interface CancellableRateLimit { 7 | val isRateLimitCancelled: Boolean 8 | 9 | /** 10 | * Cancels the token consumption of the current rate limited interaction. 11 | * 12 | * Canceling more than once is a no-op, canceling on a full bucket is also a no-op. 13 | */ 14 | fun cancelRateLimit() 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/ratelimit/RateLimitInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.ratelimit 2 | 3 | import io.github.freya022.botcommands.api.core.DeclarationSite 4 | import io.github.freya022.botcommands.api.core.IDeclarationSiteHolder 5 | 6 | /** 7 | * Container for rate limiters data. 8 | */ 9 | class RateLimitInfo internal constructor( 10 | val group: String, 11 | val limiter: RateLimiter, 12 | override val declarationSite: DeclarationSite 13 | ) : IDeclarationSiteHolder { 14 | override fun toString(): String { 15 | return "RateLimitInfo(group='$group', limiter=$limiter)" 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/TextSubcommandInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text 2 | 3 | /** 4 | * Represents a text subcommand. 5 | */ 6 | interface TextSubcommandInfo : TextCommandInfo -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/TopLevelTextCommandInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text 2 | 3 | /** 4 | * Represents a top-level text command. 5 | */ 6 | interface TopLevelTextCommandInfo : TextCommandInfo { 7 | /** 8 | * Category of this text command, only used in the built-in help command. 9 | */ 10 | val category: String 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/annotations/Category.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.annotations 2 | 3 | /** 4 | * Specifies the global category of this top-level command. 5 | */ 6 | @Target(AnnotationTarget.CLASS) 7 | @Retention(AnnotationRetention.RUNTIME) 8 | annotation class Category(val value: String) 9 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/annotations/Hidden.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.text.builder.TextCommandBuilder 4 | import io.github.freya022.botcommands.api.core.BotOwners 5 | 6 | /** 7 | * Hides a command and its subcommands from help content and execution, 8 | * except for [bot owners][BotOwners]. 9 | * 10 | * **Note:** This applies to the command itself, not only this variation, 11 | * in other words, this applies to all commands with the same path. 12 | * 13 | * @see TextCommandBuilder.hidden DSL equivalent 14 | */ 15 | @Retention(AnnotationRetention.RUNTIME) 16 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 17 | annotation class Hidden -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/annotations/ID.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.annotations 2 | 3 | /** 4 | * Adapts the help content of this parameter as an ID of an entity (message, user, guild, channel, role...) 5 | */ 6 | @Target(AnnotationTarget.VALUE_PARAMETER) 7 | @Retention(AnnotationRetention.RUNTIME) 8 | annotation class ID 9 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/annotations/NSFW.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.annotations 2 | 3 | import io.github.freya022.botcommands.api.commands.text.builder.TextCommandBuilder 4 | 5 | /** 6 | * Marks a text command as being usable in NSFW channels only. 7 | * 8 | * ### Built-in help content 9 | * NSFW commands will be shown if requested in an NSFW channel. 10 | * 11 | * @see TextCommandBuilder.nsfw DSL equivalent 12 | */ 13 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) 14 | @Retention(AnnotationRetention.RUNTIME) 15 | annotation class NSFW -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/annotations/RequiresTextCommands.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.config.BTextConfig 4 | import io.github.freya022.botcommands.api.core.service.annotations.Condition 5 | import io.github.freya022.botcommands.internal.commands.text.RequiresTextCommandsChecker 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty 7 | 8 | /** 9 | * Prevents usage of the annotated service if text commands are [not enabled][BTextConfig.enable]. 10 | * 11 | * @see BTextConfig.enable 12 | */ 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 14 | @Condition(RequiresTextCommandsChecker::class) 15 | @ConditionalOnProperty("botcommands.text.enable", matchIfMissing = true) 16 | annotation class RequiresTextCommands -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/builder/TextSubcommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.builder 2 | 3 | interface TextSubcommandBuilder : TextCommandBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/builder/TopLevelTextCommandBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.builder 2 | 3 | interface TopLevelTextCommandBuilder : TextCommandBuilder { 4 | //TODO docs 5 | var category: String 6 | } 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/options/TextCommandParameter.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.options 2 | 3 | import io.github.freya022.botcommands.api.commands.options.CommandParameter 4 | import io.github.freya022.botcommands.api.commands.text.TextCommandVariation 5 | 6 | /** 7 | * Represents a text command parameter, 8 | * which has its value computed by an aggregation function, from one or more options. 9 | */ 10 | interface TextCommandParameter : CommandParameter { 11 | override val nestedAggregatedParameters: List 12 | 13 | override val executable: TextCommandVariation 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/options/builder/TextCommandOptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.options.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilder 4 | 5 | interface TextCommandOptionAggregateBuilder : OptionAggregateBuilder, 6 | TextOptionRegistry 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/commands/text/options/builder/TextCommandOptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.commands.text.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.options.builder.CommandOptionBuilder 4 | 5 | interface TextCommandOptionBuilder : CommandOptionBuilder { 6 | var helpExample: String? 7 | var isId: Boolean 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/EntitySelectMenu.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components 2 | 3 | import io.github.freya022.botcommands.api.components.event.EntitySelectEvent 4 | import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu as JDAEntitySelectMenu 5 | 6 | interface EntitySelectMenu : JDAEntitySelectMenu, 7 | AwaitableComponent, 8 | IGroupHolder { 9 | 10 | override fun asEnabled(): EntitySelectMenu = withDisabled(false) 11 | 12 | override fun asDisabled(): EntitySelectMenu = withDisabled(true) 13 | 14 | override fun withDisabled(disabled: Boolean): EntitySelectMenu 15 | 16 | override fun getId(): String 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/IGroupHolder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components 2 | 3 | interface IGroupHolder : IdentifiableComponent { 4 | val group: ComponentGroup? 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/StringSelectMenu.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components 2 | 3 | import io.github.freya022.botcommands.api.components.event.StringSelectEvent 4 | import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu as JDAStringSelectMenu 5 | 6 | interface StringSelectMenu : JDAStringSelectMenu, 7 | AwaitableComponent, 8 | IGroupHolder { 9 | 10 | override fun asEnabled(): StringSelectMenu = withDisabled(false) 11 | 12 | override fun asDisabled(): StringSelectMenu = withDisabled(true) 13 | 14 | override fun withDisabled(disabled: Boolean): StringSelectMenu 15 | 16 | override fun getId(): String 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/annotations/RequiresComponents.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.db.annotations.RequiresDatabase 4 | import io.github.freya022.botcommands.api.core.service.annotations.Condition 5 | import io.github.freya022.botcommands.internal.components.RequiresComponentsChecker 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty 7 | 8 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 9 | @Condition(RequiresComponentsChecker::class) 10 | @ConditionalOnProperty("botcommands.components.enable") 11 | @RequiresDatabase 12 | annotation class RequiresComponents -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/BaseComponentBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | 5 | interface BaseComponentBuilder> : 6 | IComponentBuilder, 7 | ITimeoutableComponent, 8 | IActionableComponent, 9 | IConstrainableComponent, 10 | IUniqueComponent { 11 | 12 | override val context: BContext 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/IComponentBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder 2 | 3 | import io.github.freya022.botcommands.internal.components.ComponentDSL 4 | 5 | @ComponentDSL 6 | interface IComponentBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/button/ButtonBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.button 2 | 3 | import io.github.freya022.botcommands.api.components.Button 4 | import io.github.freya022.botcommands.api.components.builder.BaseComponentBuilder 5 | import javax.annotation.CheckReturnValue 6 | 7 | interface ButtonBuilder> : BaseComponentBuilder { 8 | @CheckReturnValue 9 | fun build(): Button 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/button/EphemeralButtonBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.button 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IEphemeralActionableComponent 4 | import io.github.freya022.botcommands.api.components.builder.IEphemeralTimeoutableComponent 5 | import io.github.freya022.botcommands.api.components.event.ButtonEvent 6 | 7 | interface EphemeralButtonBuilder : ButtonBuilder, 8 | IEphemeralActionableComponent, 9 | IEphemeralTimeoutableComponent -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/button/PersistentButtonBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.button 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IPersistentActionableComponent 4 | import io.github.freya022.botcommands.api.components.builder.IPersistentTimeoutableComponent 5 | 6 | interface PersistentButtonBuilder : ButtonBuilder, 7 | IPersistentActionableComponent, 8 | IPersistentTimeoutableComponent -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/group/ComponentGroupBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.group 2 | 3 | import io.github.freya022.botcommands.api.components.ComponentGroup 4 | import io.github.freya022.botcommands.api.components.builder.IComponentBuilder 5 | import io.github.freya022.botcommands.api.components.builder.ITimeoutableComponent 6 | 7 | interface ComponentGroupBuilder> : 8 | IComponentBuilder, 9 | ITimeoutableComponent { 10 | 11 | fun build(): ComponentGroup 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/group/EphemeralComponentGroupBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.group 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IEphemeralTimeoutableComponent 4 | 5 | interface EphemeralComponentGroupBuilder : 6 | ComponentGroupBuilder, 7 | IEphemeralTimeoutableComponent -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/builder/group/PersistentComponentGroupBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.builder.group 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IPersistentTimeoutableComponent 4 | 5 | interface PersistentComponentGroupBuilder : 6 | ComponentGroupBuilder, 7 | IPersistentTimeoutableComponent -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/data/ComponentTimeoutData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.data 2 | 3 | data class ComponentTimeoutData internal constructor(val componentId: Int) : ITimeoutData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/data/GroupTimeoutData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.data 2 | 3 | data class GroupTimeoutData internal constructor(private val _componentIds: List) : ITimeoutData { 4 | val componentIds: List by lazy { 5 | _componentIds.map { it.toString() } 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/data/ITimeoutData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.data 2 | 3 | sealed interface ITimeoutData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/options/ComponentOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.options 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.ComponentData 4 | import io.github.freya022.botcommands.api.core.options.Option 5 | 6 | /** 7 | * A parameter annotated with [@ComponentData][ComponentData] from a persistent component handler. 8 | */ 9 | interface ComponentOption : Option { 10 | 11 | 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/serialization/annotations/SerializableComponentData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.serialization.annotations 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.ComponentData 4 | import io.github.freya022.botcommands.api.components.serialization.GlobalComponentDataSerializer 5 | 6 | /** 7 | * Same as [@ComponentData][ComponentData], 8 | * but also generates a resolver which (de)serializes the value using the [GlobalComponentDataSerializer]. 9 | */ 10 | @ComponentData 11 | @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.ANNOTATION_CLASS) 12 | annotation class SerializableComponentData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/serialization/annotations/SerializableTimeoutData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.serialization.annotations 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.TimeoutData 4 | import io.github.freya022.botcommands.api.components.serialization.GlobalComponentDataSerializer 5 | 6 | /** 7 | * Same as [@TimeoutData][TimeoutData], 8 | * but also generates a resolver which (de)serializes the value using the [GlobalComponentDataSerializer]. 9 | */ 10 | @TimeoutData 11 | @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.ANNOTATION_CLASS) 12 | annotation class SerializableTimeoutData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/serialization/exceptions/ComponentSerializationException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.serialization.exceptions 2 | 3 | import io.github.freya022.botcommands.api.parameters.resolvers.ComponentParameterResolver 4 | import io.github.freya022.botcommands.api.parameters.resolvers.TimeoutParameterResolver 5 | 6 | /** 7 | * An exception thrown when [ComponentParameterResolver.serialize] or [TimeoutParameterResolver.serialize] fails. 8 | */ 9 | class ComponentSerializationException : RuntimeException { 10 | 11 | constructor(message: String) : super(message) 12 | constructor(message: String, cause: Throwable) : super(message, cause) 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/components/timeout/options/TimeoutOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.components.timeout.options 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.TimeoutData 4 | import io.github.freya022.botcommands.api.core.options.Option 5 | 6 | /** 7 | * A parameter annotated with [@TimeoutData][TimeoutData] from a persistent timeout handler. 8 | */ 9 | interface TimeoutOption : Option { 10 | 11 | 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/ICoroutineEventManagerSupplier.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core 2 | 3 | import dev.minn.jda.ktx.events.CoroutineEventManager 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService 6 | 7 | /** 8 | * Interface to supply a [CoroutineEventManager], ran once at startup. 9 | * 10 | * **Usage**: Register your instance as a service with [@BService][BService]. 11 | * 12 | * @see InterfacedService @InterfacedService 13 | */ 14 | @InterfacedService(acceptMultiple = false) 15 | fun interface ICoroutineEventManagerSupplier { 16 | fun get(): CoroutineEventManager 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/annotations/IgnoreStackFrame.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.DeclarationSite 4 | import io.github.freya022.botcommands.api.core.db.Database 5 | 6 | /** 7 | * Ignores stack frames of this class. 8 | * 9 | * ## Use in [Database] 10 | * This is useful when retrieving the logger of traced prepared statements, 11 | * see [Database] for details on how tracing works. 12 | * 13 | * ## When declaring commands 14 | * When an error happens while declaring a command (such as when one is duplicated), 15 | * the declaration site is used to tell where a command was created at. 16 | * 17 | * See [DeclarationSite]. 18 | * 19 | * @see Database 20 | */ 21 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE) 22 | @Retention(AnnotationRetention.RUNTIME) 23 | annotation class IgnoreStackFrame -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/config/DevConfig.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.config 2 | 3 | @RequiresOptIn(message = "This config property needs to be understood well and only used during development", level = RequiresOptIn.Level.WARNING) 4 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER) 5 | @Retention(AnnotationRetention.BINARY) 6 | annotation class DevConfig 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/config/application/cache/DatabaseApplicationCommandsCacheConfig.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.config.application.cache 2 | 3 | interface DatabaseApplicationCommandsCacheConfig : ApplicationCommandsCacheConfig 4 | 5 | class DatabaseApplicationCommandsCacheConfigBuilder internal constructor( 6 | 7 | ) : ApplicationCommandsCacheConfigBuilder(), 8 | DatabaseApplicationCommandsCacheConfig { 9 | 10 | @JvmSynthetic 11 | override fun build(): DatabaseApplicationCommandsCacheConfig = object : BuiltApplicationCommandsCacheConfig(this), 12 | DatabaseApplicationCommandsCacheConfig { 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/db/annotations/RequiresDatabase.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.db.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.db.ConnectionSupplier 4 | import io.github.freya022.botcommands.api.core.service.annotations.Dependencies 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean 6 | 7 | /** 8 | * Prevents usage of the annotated service if the required [ConnectionSupplier] is not found. 9 | * 10 | * @see ConnectionSupplier 11 | */ 12 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 13 | @Dependencies(ConnectionSupplier::class) 14 | @ConditionalOnBean(ConnectionSupplier::class) 15 | annotation class RequiresDatabase -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/events/BEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.events 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | 5 | abstract class BEvent internal constructor(override val context: BContext) : BGenericEvent 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/events/BGenericEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.events 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | 5 | interface BGenericEvent { 6 | val context: BContext 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/events/BStatusChangeEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.events 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.core.BContext.Status 5 | 6 | class BStatusChangeEvent internal constructor(context: BContext, val oldStatus: Status, val newStatus: Status) : BEvent(context) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/events/FirstGuildReadyEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.events 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import net.dv8tion.jda.api.events.guild.GuildReadyEvent 5 | 6 | /** 7 | * Indicates that the first [GuildReadyEvent] was fired. 8 | * 9 | * @see InjectedJDAEvent 10 | */ 11 | class FirstGuildReadyEvent internal constructor(context: BContext, val event: GuildReadyEvent) : BEvent(context) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/exceptions/InvalidChannelTypeException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.exceptions 2 | 3 | import io.github.freya022.botcommands.api.core.utils.retrieveThreadChannelById 4 | 5 | /** 6 | * Exception thrown when retrieving a channel by ID, but the type is incorrect. 7 | * 8 | * @see retrieveThreadChannelById 9 | */ 10 | class InvalidChannelTypeException(message: String) : IllegalArgumentException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/options/builder/OptionAggregateBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.options.builder 2 | 3 | interface OptionAggregateBuilder> : OptionRegistry 4 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/options/builder/OptionBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.commands.CommandDSL 4 | 5 | @CommandDSL 6 | interface OptionBuilder 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/ClassGraphProcessor.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service 2 | 3 | import io.github.classgraph.ClassInfo 4 | import io.github.classgraph.MethodInfo 5 | import java.lang.reflect.Executable 6 | import kotlin.reflect.KClass 7 | 8 | interface ClassGraphProcessor { 9 | fun processClass(serviceContainer: ServiceContainer, classInfo: ClassInfo, kClass: KClass<*>, isService: Boolean) {} 10 | 11 | fun processMethod( 12 | serviceContainer: ServiceContainer, 13 | methodInfo: MethodInfo, 14 | method: Executable, 15 | classInfo: ClassInfo, 16 | kClass: KClass<*>, 17 | isServiceFactory: Boolean, 18 | ) {} 19 | 20 | fun postProcess(serviceContainer: ServiceContainer) {} 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/LazyService.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service 2 | 3 | interface LazyService : Lazy { 4 | fun canCreateService(): Boolean 5 | 6 | fun getServiceError(): ServiceError? 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/BConfiguration.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | /** 4 | * No-op annotation to mark a `class` / `object` as containing service factories. 5 | * 6 | * As a reminder, service factories must either be static, be in an `object`, 7 | * or be declared in a service class (in which case you need to use [@BService][BService] instead). 8 | * 9 | * @see BService @BService 10 | */ 11 | @MustBeDocumented 12 | @Target(AnnotationTarget.CLASS) 13 | annotation class BConfiguration 14 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/InjectedService.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.service.ServiceContainer 4 | 5 | /** 6 | * No-op annotation marking a class as an injected service. 7 | * 8 | * The service needs to be instantiated and registered manually via [ServiceContainer.putService]. 9 | * 10 | * @see BService @BService 11 | * @see MissingServiceMessage @MissingServiceMessage 12 | */ 13 | @MustBeDocumented 14 | @Target(AnnotationTarget.CLASS) 15 | annotation class InjectedService 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/Lazy.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | import org.springframework.context.annotation.Lazy as SpringLazy 4 | 5 | /** 6 | * Defines a service provider as being lazy. 7 | * 8 | * A lazy service provider is only used when the service it provides gets requested. 9 | * 10 | * @see BService @BService 11 | */ 12 | @MustBeDocumented 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 14 | @SpringLazy 15 | annotation class Lazy -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/MissingServiceMessage.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | /** 4 | * Defines a message to display when a service of that type has no provider. 5 | * 6 | * @see BService @BService 7 | * @see InterfacedService @InterfacedService 8 | * @see InjectedService @InjectedService 9 | */ 10 | @MustBeDocumented 11 | @Target(AnnotationTarget.CLASS) 12 | annotation class MissingServiceMessage(@get:JvmName("value") val message: String) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/Primary.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | import org.springframework.context.annotation.Primary as SpringPrimary 4 | 5 | /** 6 | * Defines a *primary* service provider. 7 | * 8 | * A primary service provider is prioritized over a normal service provider, 9 | * having multiple primary service providers is allowed, but the service's type might not be retrievable. 10 | * 11 | * See the "Primary providers" section in [@BService][BService]. 12 | * 13 | * @see BService @BService 14 | */ 15 | @MustBeDocumented 16 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 17 | @SpringPrimary 18 | annotation class Primary 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/ServiceName.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | /** 4 | * Sets the name of this service. 5 | * 6 | * This annotation can be used for service declarations as well as when getting services 7 | * 8 | * @see BService @BService 9 | * @see BService.name 10 | */ 11 | @MustBeDocumented 12 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.ANNOTATION_CLASS) 13 | annotation class ServiceName( 14 | /** 15 | * The unique name of this service. 16 | */ 17 | val value: String 18 | ) 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/service/annotations/ServicePriority.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.service.annotations 2 | 3 | /** 4 | * Sets the priority of this service. 5 | * 6 | * Higher value = Will be loaded first/shown first in interfaced services lists. 7 | * 8 | * By default, service providers are sorted: 9 | * - By their priority 10 | * - If at the same priority, service factories are prioritized 11 | * - By their name (ascending alphabetical order) 12 | * 13 | * @see BService @BService 14 | * @see BService.priority 15 | */ 16 | @MustBeDocumented 17 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 18 | annotation class ServicePriority(val value: Int) 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/utils/Jackson.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.utils 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference 4 | import com.fasterxml.jackson.module.kotlin.jacksonTypeRef 5 | 6 | /** 7 | * Creates a [TypeReference] of type [T]. 8 | */ 9 | @Deprecated( 10 | message = "Replaced by jacksonTypeRef", 11 | replaceWith = ReplaceWith("jacksonTypeRef()", "com.fasterxml.jackson.module.kotlin.jacksonTypeRef") 12 | ) 13 | inline fun typeReferenceOf() = jacksonTypeRef() -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/utils/NIO.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.utils 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | import java.nio.file.StandardOpenOption 6 | 7 | fun Path.overwriteBytes(bytes: ByteArray): Path = 8 | Files.write(this, bytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/utils/Strings.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("StringUtils") 2 | 3 | package io.github.freya022.botcommands.api.core.utils 4 | 5 | fun String.nullIfEmpty(): String? = when { 6 | isEmpty() -> null 7 | else -> this 8 | } 9 | 10 | fun String.nullIfBlank(): String? = when { 11 | isBlank() -> null 12 | else -> this 13 | } 14 | 15 | fun Iterable.joinWithQuote(transform: ((T) -> CharSequence)? = null) = joinToString(separator = "', '", prefix = "'", postfix = "'", transform = transform) 16 | 17 | fun Iterable.joinAsList(linePrefix: String = " -", transform: ((T) -> CharSequence)? = null) = joinToString(prefix = "$linePrefix ", separator = "\n$linePrefix ", transform = transform) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/core/waiter/CompletedFutureEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.core.waiter 2 | 3 | import net.dv8tion.jda.api.events.Event 4 | import java.util.concurrent.Future 5 | 6 | /** 7 | * Functional interface for [EventWaiterBuilder.setOnComplete], 8 | * provides a [Future] and **either** the event **or** an exception. 9 | * 10 | * @param T The JDA event being waited for 11 | */ 12 | fun interface CompletedFutureEvent { 13 | fun accept(future: Future, e: T?, t: Throwable?) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/emojis/annotations/RequiresAppEmojis.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.emojis.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.Condition 4 | import io.github.freya022.botcommands.internal.emojis.RequiresAppEmojisChecker 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty 6 | 7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 8 | @Condition(RequiresAppEmojisChecker::class) 9 | @ConditionalOnProperty("botcommands.app.emojis.enable") 10 | annotation class RequiresAppEmojis -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/emojis/exceptions/EmojiAlreadyExistsException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.emojis.exceptions 2 | 3 | /** 4 | * Indicates that an application emoji has more than one definition with the same final emoji name. 5 | */ 6 | class EmojiAlreadyExistsException internal constructor(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/emojis/exceptions/NoEmojiResourceException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.emojis.exceptions 2 | 3 | /** 4 | * Indicates that no resource could be found for an application emoji's asset pattern. 5 | */ 6 | class NoEmojiResourceException internal constructor(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/emojis/exceptions/NonUniqueEmojiResourceException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.emojis.exceptions 2 | 3 | /** 4 | * Indicates that multiple resources were found for an application emoji's asset pattern. 5 | */ 6 | class NonUniqueEmojiResourceException internal constructor(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/emojis/exceptions/OutOfAppEmojisException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.emojis.exceptions 2 | 3 | /** 4 | * Indicates that all application emoji slots were used. 5 | */ 6 | class OutOfAppEmojisException internal constructor(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/Localization.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization 2 | 3 | /** 4 | * Create a new localization entry, this binds a key (from a templated string) to the value 5 | * 6 | * @receiver The key from the templated string 7 | * @param value The value to assign it to 8 | * 9 | * @see Localization 10 | * 11 | * @see localize LocalizationTemplate.localize 12 | */ 13 | infix fun String.to(value: Any): Localization.Entry = Localization.Entry.entry(this, value) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/LocalizationTemplate.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization 2 | 3 | import io.github.freya022.botcommands.api.core.utils.mapToArray 4 | 5 | /** 6 | * Represents an entire localizable string, with parameters. 7 | * 8 | * You can implement your own template, the default one is [DefaultLocalizationTemplate]. 9 | * 10 | * @see DefaultLocalizationTemplate 11 | */ 12 | interface LocalizationTemplate { 13 | /** 14 | * Processes the localization template and replaces the named parameters by their values 15 | */ 16 | fun localize(vararg args: Localization.Entry): String 17 | } 18 | 19 | /** 20 | * Processes the localization template and replaces the named parameters by their values 21 | */ 22 | fun LocalizationTemplate.localize(vararg args: Pair): String = 23 | localize(*args.mapToArray { (k, v) -> Localization.Entry.entry(k, v) }) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/arguments/FormattableArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization.arguments 2 | 3 | import io.github.freya022.botcommands.api.localization.LocalizationTemplate 4 | import io.github.freya022.botcommands.internal.localization.LocalizableArgument 5 | 6 | /** 7 | * A formattable argument from a [LocalizationTemplate]. 8 | */ 9 | interface FormattableArgument : LocalizableArgument { 10 | val argumentName: String 11 | fun format(obj: Any): String 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/arguments/JavaFormattableArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization.arguments 2 | 3 | import java.util.* 4 | 5 | class JavaFormattableArgument( 6 | override val argumentName: String, 7 | private val formatter: String, 8 | private val locale: Locale 9 | ) : FormattableArgument { 10 | override fun format(obj: Any): String = formatter.format(locale, obj) 11 | 12 | override fun toString(): String { 13 | return "JavaFormattableArgument(argumentName='$argumentName', formatter='$formatter', locale=$locale)" 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/arguments/MessageFormatArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization.arguments 2 | 3 | import java.text.MessageFormat 4 | import java.util.* 5 | import java.util.concurrent.locks.ReentrantLock 6 | import kotlin.concurrent.withLock 7 | 8 | class MessageFormatArgument( 9 | override val argumentName: String, 10 | formatter: String, 11 | locale: Locale 12 | ) : FormattableArgument { 13 | private val lock = ReentrantLock() 14 | private val formatter = MessageFormat(formatter, locale) 15 | 16 | override fun format(obj: Any): String = lock.withLock { formatter.format(arrayOf(obj)) } 17 | 18 | override fun toString(): String { 19 | return "MessageFormatArgument(argumentName='$argumentName', formatter=${formatter.toPattern()})" 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/arguments/factories/FormattableArgumentFactory.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization.arguments.factories 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BService 4 | import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService 5 | import io.github.freya022.botcommands.api.localization.arguments.FormattableArgument 6 | import java.util.* 7 | 8 | /** 9 | * Factory for [formattable arguments][FormattableArgument]. 10 | * 11 | * **Usage**: Register your instance as a service with [@BService][BService]. 12 | * 13 | * @see FormattableArgument 14 | * @see InterfacedService @InterfacedService 15 | */ 16 | @InterfacedService(acceptMultiple = true) 17 | interface FormattableArgumentFactory { 18 | val regex: Regex 19 | 20 | fun get(matchResult: MatchResult, locale: Locale): FormattableArgument 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/localization/arguments/factories/JavaFormattableArgumentFactory.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.localization.arguments.factories 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BService 4 | import io.github.freya022.botcommands.api.localization.arguments.FormattableArgument 5 | import io.github.freya022.botcommands.api.localization.arguments.JavaFormattableArgument 6 | import java.util.* 7 | 8 | @BService 9 | class JavaFormattableArgumentFactory : FormattableArgumentFactory { 10 | override val regex: Regex = Regex("""(\w+):(%.+?)""") 11 | 12 | override fun get(matchResult: MatchResult, locale: Locale): FormattableArgument { 13 | val (formatterName, formatter) = matchResult.destructured 14 | return JavaFormattableArgument(formatterName, formatter, locale) 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/modals/annotations/ModalData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.modals.annotations 2 | 3 | import io.github.freya022.botcommands.api.modals.ModalBuilder 4 | 5 | /** 6 | * Sets this parameter as data coming from [ModalBuilder.bindTo]. 7 | * 8 | * The data supplied in the method above must be in the same order as the modal handler parameters, 9 | * and must match the types. 10 | * 11 | * @see ModalHandler @ModalHandler 12 | * @see ModalInput @ModalInput 13 | */ 14 | @Target(AnnotationTarget.VALUE_PARAMETER) 15 | @Retention(AnnotationRetention.RUNTIME) 16 | annotation class ModalData 17 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/modals/annotations/ModalInput.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.modals.annotations 2 | 3 | import io.github.freya022.botcommands.api.modals.Modals 4 | 5 | /** 6 | * Set this parameter as a modal input. 7 | * 8 | * The specified input name must be the same as the input name given in, for example, [Modals.createTextInput]. 9 | * 10 | * @see ModalData @ModalData 11 | * @see ModalHandler @ModalHandler 12 | */ 13 | @Target(AnnotationTarget.VALUE_PARAMETER) 14 | @Retention(AnnotationRetention.RUNTIME) 15 | annotation class ModalInput( 16 | /** 17 | * The name of the modal input.
18 | * Must match the input name provided in, for example, [Modals.createTextInput]. 19 | */ 20 | @get:JvmName("value") val name: String 21 | ) 22 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/modals/annotations/RequiresModals.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.modals.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.config.BModalsConfig 4 | import io.github.freya022.botcommands.api.core.service.annotations.Condition 5 | import io.github.freya022.botcommands.internal.modals.RequiresModalsChecker 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty 7 | 8 | /** 9 | * Prevents usage of the annotated service if modals are [not enabled][BModalsConfig.enable]. 10 | * 11 | * @see BModalsConfig.enable 12 | */ 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.ANNOTATION_CLASS) 14 | @Condition(RequiresModalsChecker::class) 15 | @ConditionalOnProperty("botcommands.modals.enable", matchIfMissing = true) 16 | annotation class RequiresModals -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/modals/options/ModalOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.modals.options 2 | 3 | import io.github.freya022.botcommands.api.core.options.Option 4 | import io.github.freya022.botcommands.api.modals.annotations.ModalData 5 | import io.github.freya022.botcommands.api.modals.annotations.ModalHandler 6 | 7 | /** 8 | * A parameter annotated with [@ModalData][ModalData] from a [modal handler][ModalHandler]. 9 | */ 10 | interface ModalOption : Option { 11 | 12 | 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/PaginationTimeoutConsumer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination 2 | 3 | typealias SuspendingPaginationTimeoutConsumer = suspend (T) -> Unit 4 | 5 | fun interface BlockingPaginationTimeoutConsumer> { 6 | fun accept(paginator: T) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/TimeoutInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination 2 | 3 | import kotlin.time.Duration 4 | 5 | data class TimeoutInfo>( 6 | val timeout: Duration, 7 | val onTimeout: (suspend (T) -> Unit)? 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/custom/AbstractCustomPaginationBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.custom 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.AbstractPagination 5 | import io.github.freya022.botcommands.api.pagination.AbstractPaginationBuilder 6 | 7 | /** 8 | * Most basic paginator builder. 9 | * 10 | * @param T Type of the pagination builder 11 | * @param R Type of the built pagination 12 | */ 13 | abstract class AbstractCustomPaginationBuilder, R : AbstractPagination>( 14 | context: BContext 15 | ) : AbstractPaginationBuilder(context) 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/custom/CustomPaginationBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.custom 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.Paginators 5 | 6 | /** 7 | * Builds a [CustomPagination]. 8 | * 9 | * @see Paginators.customPagination 10 | * @see Paginators.singlePage 11 | */ 12 | class CustomPaginationBuilder internal constructor( 13 | context: BContext, 14 | val maxPages: Int, 15 | val pageEditor: CustomPageEditor 16 | ) : AbstractCustomPaginationBuilder(context) { 17 | override fun build(): CustomPagination = CustomPagination(context, this) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/MenuBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.Paginators 5 | 6 | /** 7 | * Builds a [Menu]. 8 | * 9 | * @param E Type of the entries 10 | * 11 | * @see Paginators.menu 12 | */ 13 | class MenuBuilder internal constructor( 14 | context: BContext, 15 | entries: List 16 | ) : AbstractMenuBuilder, Menu>(context, entries) { 17 | override fun build(): Menu = Menu(context, this) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/MenuPage.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu 2 | 3 | data class MenuPage(val content: String, val entries: List) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/buttonized/ChoiceCallback.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu.buttonized 2 | 3 | import io.github.freya022.botcommands.api.components.event.ButtonEvent 4 | 5 | typealias SuspendingChoiceCallback = suspend (event: ButtonEvent, entry: E) -> Unit 6 | 7 | /** 8 | * Callback called when an item has been chosen in a [ButtonMenu] 9 | * 10 | * @param E Type of the entries 11 | */ 12 | fun interface BlockingChoiceCallback { 13 | /** 14 | * Runs the callback 15 | * 16 | * @param event The [ButtonEvent] from the interacting user 17 | * @param entry The selected entry from the [ButtonMenu] elements 18 | */ 19 | fun accept(event: ButtonEvent, entry: E) 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/transformer/EntryTransformer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu.transformer 2 | 3 | /** 4 | * Interface to transform pagination entries into strings 5 | * 6 | * @param T Type of the pagination entry 7 | */ 8 | fun interface EntryTransformer { 9 | fun toString(entry: T): String 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/transformer/IMentionableTransformer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu.transformer 2 | 3 | import net.dv8tion.jda.api.entities.IMentionable 4 | 5 | class IMentionableTransformer : EntryTransformer { 6 | override fun toString(entry: IMentionable): String = entry.asMention 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/menu/transformer/StringTransformer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.menu.transformer 2 | 3 | class StringTransformer : EntryTransformer { 4 | override fun toString(entry: Any): String = entry.toString() 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/nested/NestedPaginationItem.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.nested 2 | 3 | import io.github.freya022.botcommands.api.components.utils.SelectContent 4 | import io.github.freya022.botcommands.api.pagination.AbstractPagination 5 | import io.github.freya022.botcommands.api.pagination.PageEditor 6 | 7 | data class NestedPaginationItem>( 8 | val content: SelectContent, 9 | val maxPages: Int, 10 | val pageEditor: PageEditor 11 | ) { 12 | var page = 0 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/nested/NestedPaginator.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.nested 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.Paginators 5 | 6 | /** 7 | * A paginator which wraps a paginator, with a select menu to switch between them. 8 | * 9 | * @see Paginators.nestedPagination 10 | */ 11 | class NestedPaginator internal constructor( 12 | context: BContext, 13 | builder: NestedPaginatorBuilder 14 | ) : AbstractNestedPaginator( 15 | context, 16 | builder 17 | ) { 18 | object Defaults { 19 | /** @see AbstractNestedPaginatorBuilder.usePaginatorControls */ 20 | @JvmStatic 21 | var usePaginatorControls = false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/nested/NestedPaginatorBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.nested 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.Paginators 5 | 6 | /** 7 | * Builds a [NestedPaginator]. 8 | * 9 | * @see Paginators.nestedPagination 10 | */ 11 | class NestedPaginatorBuilder internal constructor( 12 | context: BContext 13 | ) : AbstractNestedPaginatorBuilder(context) { 14 | override fun build(): NestedPaginator = NestedPaginator(context, this) 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/pagination/paginator/PaginatorBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.pagination.paginator 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.pagination.PageEditor 5 | import io.github.freya022.botcommands.api.pagination.Paginators 6 | 7 | /** 8 | * Builds a [Paginator]. 9 | * 10 | * @see Paginators.paginator 11 | */ 12 | class PaginatorBuilder internal constructor( 13 | context: BContext, 14 | val maxPages: Int, 15 | val pageEditor: PageEditor 16 | ) : AbstractPaginatorBuilder(context) { 17 | override fun build(): Paginator = Paginator(context, this) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/parameters/ResolverData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.parameters 2 | 3 | import io.github.freya022.botcommands.api.commands.application.ApplicationCommandResolverData 4 | 5 | /** 6 | * Marker interface for data passed when requesting for a parameter resolver. 7 | * 8 | * @see ApplicationCommandResolverData 9 | */ 10 | interface ResolverData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/api/parameters/resolvers/IParameterResolver.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.api.parameters.resolvers 2 | 3 | interface IParameterResolver> -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/autoconfigure/BotCommandsAutoConfiguration.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.autoconfigure 2 | 3 | import io.github.freya022.botcommands.internal.core.SpringBotCommandsConfiguration 4 | import org.springframework.boot.autoconfigure.AutoConfiguration 5 | import org.springframework.context.annotation.Import 6 | 7 | @AutoConfiguration 8 | @Import(SpringBotCommandsConfiguration::class) 9 | internal open class BotCommandsAutoConfiguration -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/CommandDSL.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands 2 | 3 | @DslMarker 4 | internal annotation class CommandDSL 5 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/autobuilder/metadata/ApplicationFunctionMetadata.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.autobuilder.metadata 2 | 3 | import io.github.freya022.botcommands.api.commands.CommandPath 4 | import io.github.freya022.botcommands.api.commands.application.ApplicationCommand 5 | import io.github.freya022.botcommands.internal.commands.autobuilder.metadata.CommandFunctionMetadata 6 | import io.github.freya022.botcommands.internal.core.ClassPathFunction 7 | 8 | internal abstract class ApplicationFunctionMetadata( 9 | classPathFunction: ClassPathFunction, 10 | annotation: A, 11 | path: CommandPath, 12 | val commandId: String? 13 | ) : CommandFunctionMetadata(classPathFunction, ApplicationCommand::class, annotation, path) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/autobuilder/metadata/MessageContextFunctionMetadata.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.autobuilder.metadata 2 | 3 | import io.github.freya022.botcommands.api.commands.CommandPath 4 | import io.github.freya022.botcommands.api.commands.application.context.annotations.JDAMessageCommand 5 | import io.github.freya022.botcommands.internal.core.ClassPathFunction 6 | 7 | internal class MessageContextFunctionMetadata( 8 | classPathFunction: ClassPathFunction, 9 | annotation: JDAMessageCommand, 10 | path: CommandPath, 11 | commandId: String? 12 | ) : ApplicationFunctionMetadata(classPathFunction, annotation, path, commandId) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/autobuilder/metadata/SlashFunctionMetadata.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.autobuilder.metadata 2 | 3 | import io.github.freya022.botcommands.api.commands.CommandPath 4 | import io.github.freya022.botcommands.api.commands.application.slash.annotations.JDASlashCommand 5 | import io.github.freya022.botcommands.internal.core.ClassPathFunction 6 | 7 | internal class SlashFunctionMetadata( 8 | classPathFunction: ClassPathFunction, 9 | annotation: JDASlashCommand, 10 | path: CommandPath, 11 | commandId: String? 12 | ) : ApplicationFunctionMetadata(classPathFunction, annotation, path, commandId) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/autobuilder/metadata/UserContextFunctionMetadata.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.autobuilder.metadata 2 | 3 | import io.github.freya022.botcommands.api.commands.CommandPath 4 | import io.github.freya022.botcommands.api.commands.application.context.annotations.JDAUserCommand 5 | import io.github.freya022.botcommands.internal.core.ClassPathFunction 6 | 7 | internal class UserContextFunctionMetadata( 8 | classPathFunction: ClassPathFunction, 9 | annotation: JDAUserCommand, 10 | path: CommandPath, 11 | commandId: String? 12 | ) : ApplicationFunctionMetadata(classPathFunction, annotation, path, commandId) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/cache/ApplicationCommandsCache.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.cache 2 | 3 | internal interface ApplicationCommandsCache { 4 | suspend fun tryRead(): ApplicationCommandsData 5 | 6 | suspend fun write(commandBytes: ByteArray, metadataBytes: ByteArray) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/cache/ApplicationCommandsData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.cache 2 | 3 | internal class ApplicationCommandsData internal constructor( 4 | internal val commands: String?, 5 | internal val metadata: String?, 6 | ) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/cache/NullApplicationCommandsCache.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.cache 2 | 3 | internal data object NullApplicationCommandsCache : ApplicationCommandsCache { 4 | override suspend fun tryRead(): ApplicationCommandsData { 5 | return ApplicationCommandsData(null, null) 6 | } 7 | 8 | override suspend fun write(commandBytes: ByteArray, metadataBytes: ByteArray) {} 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/cache/factory/ApplicationCommandsCacheFactory.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.cache.factory 2 | 3 | import io.github.freya022.botcommands.api.core.config.application.cache.ApplicationCommandsCacheConfig 4 | import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService 5 | import io.github.freya022.botcommands.internal.commands.application.cache.ApplicationCommandsCache 6 | import net.dv8tion.jda.api.entities.Guild 7 | 8 | @InterfacedService(acceptMultiple = false) 9 | internal sealed interface ApplicationCommandsCacheFactory { 10 | val cacheConfig: ApplicationCommandsCacheConfig 11 | 12 | fun create(guild: Guild?): ApplicationCommandsCache 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/context/message/options/builder/MessageCommandOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.context.message.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.message.options.builder.MessageCommandOptionBuilder 4 | import io.github.freya022.botcommands.internal.commands.application.options.builder.ApplicationCommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 6 | 7 | internal class MessageCommandOptionBuilderImpl internal constructor( 8 | optionParameter: OptionParameter, 9 | ) : ApplicationCommandOptionBuilderImpl(optionParameter), 10 | MessageCommandOptionBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/context/options/ContextCommandOptionImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.context.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.options.ContextCommandOption 4 | import io.github.freya022.botcommands.internal.commands.application.options.builder.ApplicationCommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.core.options.OptionImpl 6 | import io.github.freya022.botcommands.internal.core.options.OptionType 7 | 8 | internal abstract class ContextCommandOptionImpl internal constructor( 9 | optionBuilder: ApplicationCommandOptionBuilderImpl 10 | ) : OptionImpl(optionBuilder.optionParameter, OptionType.OPTION), 11 | ContextCommandOption -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/context/user/options/builder/UserCommandOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.context.user.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.context.user.options.builder.UserCommandOptionBuilder 4 | import io.github.freya022.botcommands.internal.commands.application.options.builder.ApplicationCommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 6 | 7 | internal class UserCommandOptionBuilderImpl internal constructor( 8 | optionParameter: OptionParameter, 9 | ) : ApplicationCommandOptionBuilderImpl(optionParameter), 10 | UserCommandOptionBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/diff/ApplicationCommandDiffEngine.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.diff 2 | 3 | internal interface ApplicationCommandDiffEngine { 4 | context(DiffLogger) 5 | fun checkCommands(oldCommands: List>, newCommands: List>): Boolean 6 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/options/ApplicationCommandOptionImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.ApplicationCommandOption 4 | import io.github.freya022.botcommands.internal.commands.application.options.builder.ApplicationCommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.commands.options.CommandOptionImpl 6 | 7 | internal abstract class ApplicationCommandOptionImpl internal constructor( 8 | optionBuilder: ApplicationCommandOptionBuilderImpl 9 | ) : CommandOptionImpl(optionBuilder), 10 | ApplicationCommandOption -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/options/ApplicationGeneratedOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.ApplicationCommandParameter 4 | import io.github.freya022.botcommands.internal.commands.application.options.builder.ApplicationGeneratedOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.core.options.AbstractGeneratedOption 6 | 7 | internal class ApplicationGeneratedOption internal constructor( 8 | override val parent: ApplicationCommandParameter, 9 | generatedOptionBuilder: ApplicationGeneratedOptionBuilderImpl 10 | ) : AbstractGeneratedOption(generatedOptionBuilder.optionParameter) { 11 | 12 | override val executable get() = parent.executable 13 | 14 | val generatedValueSupplier = generatedOptionBuilder.generatedValueSupplier 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/options/builder/ApplicationCommandOptionAggregateBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionAggregateBuilder 4 | import io.github.freya022.botcommands.internal.commands.options.builder.CommandOptionAggregateBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.AggregatorParameter 6 | import kotlin.reflect.KFunction 7 | 8 | internal abstract class ApplicationCommandOptionAggregateBuilderImpl> internal constructor( 9 | aggregatorParameter: AggregatorParameter, 10 | aggregator: KFunction<*>, 11 | ) : CommandOptionAggregateBuilderImpl(aggregatorParameter, aggregator), 12 | ApplicationCommandOptionAggregateBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/options/builder/ApplicationCommandOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.options.builder.ApplicationCommandOptionBuilder 4 | import io.github.freya022.botcommands.internal.commands.options.builder.CommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 6 | 7 | internal abstract class ApplicationCommandOptionBuilderImpl internal constructor( 8 | optionParameter: OptionParameter, 9 | ) : CommandOptionBuilderImpl(optionParameter), 10 | ApplicationCommandOptionBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/SlashSubcommandInfoImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash 2 | 3 | import io.github.freya022.botcommands.api.commands.INamedCommand 4 | import io.github.freya022.botcommands.api.commands.application.slash.SlashSubcommandInfo 5 | import io.github.freya022.botcommands.api.core.BContext 6 | import io.github.freya022.botcommands.internal.commands.application.slash.builder.SlashCommandBuilderImpl 7 | 8 | internal class SlashSubcommandInfoImpl internal constructor( 9 | context: BContext, 10 | topLevelInstance: TopLevelSlashCommandInfoImpl, 11 | parentInstance: INamedCommand, 12 | builder: SlashCommandBuilderImpl 13 | ) : SlashCommandInfoImpl(context, topLevelInstance, parentInstance, builder), 14 | SlashSubcommandInfo -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/autocomplete/AutocompleteInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.autocomplete 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.AutocompleteMode 4 | import io.github.freya022.botcommands.api.core.IDeclarationSiteHolder 5 | import kotlin.reflect.KFunction 6 | 7 | internal abstract class AutocompleteInfo internal constructor() : IDeclarationSiteHolder { 8 | abstract val name: String? 9 | abstract val function: KFunction<*> 10 | abstract val mode: AutocompleteMode 11 | abstract val showUserInput: Boolean 12 | abstract val autocompleteCache: AutocompleteCacheInfo? 13 | 14 | abstract fun invalidate() 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/autocomplete/builder/AutocompleteCacheInfoBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.autocomplete.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.builder.AutocompleteCacheInfoBuilder 4 | import io.github.freya022.botcommands.internal.commands.application.slash.autocomplete.AutocompleteCacheInfo 5 | 6 | internal class AutocompleteCacheInfoBuilderImpl internal constructor() : AutocompleteCacheInfoBuilder { 7 | internal fun build() = AutocompleteCacheInfo(this) 8 | 9 | override var forceCache: Boolean = false 10 | override var cacheSize: Long = 2048 11 | 12 | override var compositeKeys: List = emptyList() 13 | 14 | override var guildLocal: Boolean = false 15 | override var userLocal: Boolean = false 16 | override var channelLocal: Boolean = false 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/autocomplete/suppliers/ChoiceSupplier.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.autocomplete.suppliers 2 | 3 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent 4 | import net.dv8tion.jda.api.interactions.commands.Command 5 | 6 | internal sealed interface ChoiceSupplier { 7 | fun apply(event: CommandAutoCompleteInteractionEvent, collection: Collection): List 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/autocomplete/suppliers/ChoiceSupplierChoices.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.autocomplete.suppliers 2 | 3 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent 4 | import net.dv8tion.jda.api.interactions.commands.Command 5 | 6 | internal class ChoiceSupplierChoices(private val numChoices: Int) : ChoiceSupplier { 7 | @Suppress("UNCHECKED_CAST") 8 | override fun apply(event: CommandAutoCompleteInteractionEvent, collection: Collection): List { 9 | return collection.take(numChoices) as List 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/autocomplete/suppliers/ChoiceSupplierTransformer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.autocomplete.suppliers 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.AutocompleteTransformer 4 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent 5 | import net.dv8tion.jda.api.interactions.commands.Command 6 | 7 | internal class ChoiceSupplierTransformer( 8 | private val transformer: AutocompleteTransformer, 9 | private val numChoices: Int 10 | ) : ChoiceSupplier { 11 | @Throws(Exception::class) 12 | override fun apply(event: CommandAutoCompleteInteractionEvent, collection: Collection): List { 13 | return collection 14 | .take(numChoices) 15 | .map { transformer.apply(it) } 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/builder/mixins/TopLevelApplicationCommandBuilderMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.builder.mixins 2 | 3 | import net.dv8tion.jda.api.interactions.IntegrationType 4 | import net.dv8tion.jda.api.interactions.InteractionContextType 5 | 6 | internal interface TopLevelApplicationCommandBuilderMixin { 7 | // What TopLevelApplicationCommandBuilder has but without superinterfaces, to let us use delegates 8 | var contexts: Set 9 | var integrationTypes: Set 10 | var isDefaultLocked: Boolean 11 | var nsfw: Boolean 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/exceptions/OptionNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.exceptions 2 | 3 | internal class OptionNotFoundException(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/application/slash/options/SlashCommandOptionMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.application.slash.options 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.options.SlashCommandOption 4 | import io.github.freya022.botcommands.api.parameters.resolvers.SlashParameterResolver 5 | 6 | internal interface SlashCommandOptionMixin : SlashCommandOption { 7 | val resolver: SlashParameterResolver<*, *> 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/autobuilder/CommandAutoBuilder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.autobuilder 2 | 3 | import io.github.freya022.botcommands.api.core.service.ServiceContainer 4 | import kotlin.reflect.KClass 5 | 6 | internal interface CommandAutoBuilder { 7 | val serviceContainer: ServiceContainer 8 | val optionAnnotation: KClass 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/autobuilder/metadata/MetadataFunctionHolder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.autobuilder.metadata 2 | 3 | import kotlin.reflect.KFunction 4 | 5 | internal interface MetadataFunctionHolder { 6 | val func: KFunction<*> 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/builder/IBuilderFunctionHolder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.builder 2 | 3 | import kotlin.reflect.KFunction 4 | 5 | internal interface IBuilderFunctionHolder { 6 | val function: KFunction 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/builder/RateLimitBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.builder.RateLimitBuilder 4 | import io.github.freya022.botcommands.api.commands.ratelimit.RateLimitInfo 5 | import io.github.freya022.botcommands.api.commands.ratelimit.RateLimiter 6 | import io.github.freya022.botcommands.api.core.DeclarationSite 7 | 8 | internal class RateLimitBuilderImpl internal constructor( 9 | override val group: String, 10 | override val rateLimiter: RateLimiter 11 | ) : RateLimitBuilder { 12 | override lateinit var declarationSite: DeclarationSite 13 | 14 | internal fun build(): RateLimitInfo { 15 | return RateLimitInfo(group, rateLimiter, declarationSite) 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/options/CommandOptionImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.options 2 | 3 | import io.github.freya022.botcommands.api.commands.options.CommandOption 4 | import io.github.freya022.botcommands.internal.commands.options.builder.CommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.core.options.OptionImpl 6 | 7 | internal abstract class CommandOptionImpl internal constructor( 8 | commandOptionBuilder: CommandOptionBuilderImpl 9 | ) : OptionImpl(commandOptionBuilder), 10 | CommandOption -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/options/builder/CommandOptionAggregateBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.options.builder.CommandOptionAggregateBuilder 4 | import io.github.freya022.botcommands.internal.core.options.builder.OptionAggregateBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.AggregatorParameter 6 | import kotlin.reflect.KFunction 7 | 8 | internal abstract class CommandOptionAggregateBuilderImpl> internal constructor( 9 | aggregatorParameter: AggregatorParameter, 10 | aggregator: KFunction<*> 11 | ) : OptionAggregateBuilderImpl(aggregatorParameter, aggregator), 12 | CommandOptionAggregateBuilder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/options/builder/CommandOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.options.builder.CommandOptionBuilder 4 | import io.github.freya022.botcommands.internal.core.options.OptionImpl 5 | import io.github.freya022.botcommands.internal.core.options.builder.OptionBuilderImpl 6 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 7 | 8 | internal abstract class CommandOptionBuilderImpl internal constructor( 9 | optionParameter: OptionParameter 10 | ) : OptionBuilderImpl(optionParameter), 11 | CommandOptionBuilder { 12 | 13 | /** 14 | * Switch managed by the vararg aggregates 15 | * 16 | * @see OptionImpl.isOptionalOrNullable 17 | */ 18 | internal var isOptional: Boolean? = null 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/CancellableRateLimitImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.ratelimit 2 | 3 | import io.github.bucket4j.Bucket 4 | import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimit 5 | import java.util.concurrent.locks.ReentrantLock 6 | import kotlin.concurrent.withLock 7 | 8 | internal class CancellableRateLimitImpl internal constructor(private val bucket: Bucket) : CancellableRateLimit { 9 | private val lock = ReentrantLock() 10 | override var isRateLimitCancelled: Boolean = false 11 | 12 | override fun cancelRateLimit() = lock.withLock { 13 | if (!isRateLimitCancelled) { 14 | isRateLimitCancelled = true 15 | bucket.addTokens(1) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/ratelimit/NullCancellableRateLimit.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.ratelimit 2 | 3 | import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimit 4 | 5 | internal object NullCancellableRateLimit : CancellableRateLimit { 6 | override val isRateLimitCancelled: Boolean = false 7 | 8 | override fun cancelRateLimit() {} 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/ExecutionResult.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text 2 | 3 | internal enum class ExecutionResult { 4 | STOP, CONTINUE, OK 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TextSubcommandInfoImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text 2 | 3 | import io.github.freya022.botcommands.api.commands.text.TextSubcommandInfo 4 | import io.github.freya022.botcommands.api.core.BContext 5 | import io.github.freya022.botcommands.internal.commands.text.builder.TextSubcommandBuilderImpl 6 | 7 | internal class TextSubcommandInfoImpl( 8 | override val context: BContext, 9 | builder: TextSubcommandBuilderImpl, 10 | parentInstance: TextCommandInfoImpl 11 | ) : TextCommandInfoImpl(builder, parentInstance), 12 | TextSubcommandInfo -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/TopLevelTextCommandInfoImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text 2 | 3 | import io.github.freya022.botcommands.api.commands.text.TopLevelTextCommandInfo 4 | import io.github.freya022.botcommands.api.core.BContext 5 | import io.github.freya022.botcommands.internal.commands.text.builder.TopLevelTextCommandBuilderImpl 6 | 7 | internal class TopLevelTextCommandInfoImpl( 8 | override val context: BContext, 9 | builder: TopLevelTextCommandBuilderImpl 10 | ) : TextCommandInfoImpl(builder, null), 11 | TopLevelTextCommandInfo { 12 | 13 | override val category: String = builder.category 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/autobuilder/metadata/TextFunctionMetadata.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text.autobuilder.metadata 2 | 3 | import io.github.freya022.botcommands.api.commands.CommandPath 4 | import io.github.freya022.botcommands.api.commands.text.TextCommand 5 | import io.github.freya022.botcommands.api.commands.text.annotations.JDATextCommandVariation 6 | import io.github.freya022.botcommands.internal.commands.autobuilder.metadata.CommandFunctionMetadata 7 | import io.github.freya022.botcommands.internal.core.ClassPathFunction 8 | 9 | internal class TextFunctionMetadata( 10 | classPathFunction: ClassPathFunction, 11 | annotation: JDATextCommandVariation, 12 | path: CommandPath 13 | ) : CommandFunctionMetadata(classPathFunction, TextCommand::class, annotation, path) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/options/TextGeneratedOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text.options 2 | 3 | import io.github.freya022.botcommands.api.commands.text.options.TextCommandParameter 4 | import io.github.freya022.botcommands.internal.commands.text.options.builder.TextGeneratedOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.core.options.AbstractGeneratedOption 6 | 7 | internal class TextGeneratedOption internal constructor( 8 | override val parent: TextCommandParameter, 9 | generatedOptionBuilder: TextGeneratedOptionBuilderImpl 10 | ) : AbstractGeneratedOption(generatedOptionBuilder.optionParameter) { 11 | 12 | override val executable get() = parent.executable 13 | 14 | val generatedValueSupplier = generatedOptionBuilder.generatedValueSupplier 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/commands/text/options/builder/TextCommandOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.commands.text.options.builder 2 | 3 | import io.github.freya022.botcommands.api.commands.text.options.builder.TextCommandOptionBuilder 4 | import io.github.freya022.botcommands.internal.commands.options.builder.CommandOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 6 | 7 | internal class TextCommandOptionBuilderImpl internal constructor( 8 | optionParameter: OptionParameter, 9 | internal val optionName: String, 10 | ) : CommandOptionBuilderImpl(optionParameter), 11 | TextCommandOptionBuilder { 12 | 13 | override var helpExample: String? = null 14 | override var isId: Boolean = false 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/ComponentDSL.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components 2 | 3 | @DslMarker 4 | internal annotation class ComponentDSL 5 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/ComponentType.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components 2 | 3 | import io.github.freya022.botcommands.internal.utils.throwArgument 4 | 5 | internal enum class ComponentType(val key: Int) { 6 | GROUP(0), 7 | BUTTON(1), 8 | SELECT_MENU(2); 9 | 10 | companion object { 11 | fun fromId(key: Int): ComponentType { 12 | return entries.find { it.key == key } ?: throwArgument("Unknown ComponentType: $key") 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/EphemeralHandlers.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components 2 | 3 | import java.util.concurrent.locks.ReentrantLock 4 | import kotlin.concurrent.withLock 5 | 6 | internal abstract class EphemeralHandlers { 7 | private val lock = ReentrantLock() 8 | private val map = hashMapOf() 9 | private var currentId: Int = 0 10 | 11 | operator fun get(handlerId: Int): T? = map[handlerId] 12 | 13 | fun put(handler: T) = lock.withLock { 14 | val id = currentId++ 15 | map[id] = handler 16 | return@withLock id 17 | } 18 | 19 | fun remove(handlerId: Int) = lock.withLock { 20 | map.remove(handlerId) 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/IGroupHolderMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components 2 | 3 | import io.github.freya022.botcommands.api.components.ComponentGroup 4 | import io.github.freya022.botcommands.api.components.IGroupHolder 5 | 6 | internal interface IGroupHolderMixin : IGroupHolder { 7 | override var group: ComponentGroup? 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/LifetimeType.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components 2 | 3 | import io.github.freya022.botcommands.internal.utils.throwArgument 4 | 5 | internal enum class LifetimeType(val key: Int) { 6 | PERSISTENT(0), 7 | EPHEMERAL(1); 8 | 9 | companion object { 10 | fun fromId(key: Int): LifetimeType { 11 | return entries.find { it.key == key } ?: throwArgument("Unknown LifetimeType: $key") 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/BuilderInstanceHolder.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder 2 | 3 | //See BuilderInstanceHolderImpl on how this is done internally 4 | internal interface BuilderInstanceHolder { 5 | val instance: T 6 | } 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/InstanceRetriever.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder 2 | 3 | internal class InstanceRetriever internal constructor() { 4 | lateinit var instance: T 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/mixin/BaseComponentBuilderMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder.mixin 2 | 3 | import io.github.freya022.botcommands.api.components.builder.BaseComponentBuilder 4 | 5 | internal interface BaseComponentBuilderMixin> : 6 | IComponentBuilderMixin, 7 | ITimeoutableComponentMixin, 8 | IActionableComponentMixin, 9 | IConstrainableComponentMixin, 10 | IUniqueComponentMixin -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/mixin/IComponentBuilderMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder.mixin 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IComponentBuilder 4 | import io.github.freya022.botcommands.internal.components.ComponentType 5 | import io.github.freya022.botcommands.internal.components.LifetimeType 6 | import io.github.freya022.botcommands.internal.components.builder.BuilderInstanceHolder 7 | 8 | internal interface IComponentBuilderMixin : IComponentBuilder, 9 | BuilderInstanceHolder { 10 | 11 | val componentType: ComponentType 12 | val lifetimeType: LifetimeType 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/mixin/IConstrainableComponentMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder.mixin 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IConstrainableComponent 4 | import io.github.freya022.botcommands.internal.components.builder.BuilderInstanceHolder 5 | 6 | internal interface IConstrainableComponentMixin> : IConstrainableComponent, 7 | BuilderInstanceHolder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/mixin/IUniqueComponentMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder.mixin 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IUniqueComponent 4 | import io.github.freya022.botcommands.internal.components.builder.BuilderInstanceHolder 5 | 6 | internal interface IUniqueComponentMixin> : IUniqueComponent, 7 | BuilderInstanceHolder -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/builder/mixin/impl/UniqueComponentImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.builder.mixin.impl 2 | 3 | import io.github.freya022.botcommands.api.components.builder.IUniqueComponent 4 | import io.github.freya022.botcommands.internal.components.builder.BuilderInstanceHolderImpl 5 | import io.github.freya022.botcommands.internal.components.builder.InstanceRetriever 6 | import io.github.freya022.botcommands.internal.components.builder.mixin.IUniqueComponentMixin 7 | 8 | internal class UniqueComponentImpl> internal constructor( 9 | override val instanceRetriever: InstanceRetriever 10 | ) : BuilderInstanceHolderImpl(), 11 | IUniqueComponentMixin { 12 | 13 | override var singleUse: Boolean = false 14 | 15 | override fun singleUse(singleUse: Boolean): T = applyInstance { 16 | this.singleUse = singleUse 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/data/ActionComponentData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.data 2 | 3 | import io.github.freya022.botcommands.api.components.ComponentInteractionFilter 4 | import io.github.freya022.botcommands.api.components.data.InteractionConstraints 5 | import io.github.freya022.botcommands.api.components.ratelimit.ComponentRateLimitReference 6 | import io.github.freya022.botcommands.internal.components.handler.ComponentHandler 7 | 8 | internal sealed interface ActionComponentData : ComponentData { 9 | val constraints: InteractionConstraints 10 | val singleUse: Boolean 11 | val filters: List 12 | val rateLimitReference: ComponentRateLimitReference? 13 | val handler: ComponentHandler? 14 | val group: ComponentGroupData? 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/data/ComponentData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.data 2 | 3 | import io.github.freya022.botcommands.internal.components.ComponentType 4 | import io.github.freya022.botcommands.internal.components.LifetimeType 5 | import io.github.freya022.botcommands.internal.components.data.timeout.ComponentTimeout 6 | import kotlinx.datetime.Instant 7 | import kotlin.time.Duration 8 | 9 | internal sealed interface ComponentData { 10 | val internalId: Int 11 | val componentType: ComponentType 12 | val lifetimeType: LifetimeType 13 | val expiresAt: Instant? 14 | val timeout: ComponentTimeout? 15 | val resetTimeoutOnUseDuration: Duration? 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/data/ComponentGroupData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.data 2 | 3 | import io.github.freya022.botcommands.internal.components.ComponentType 4 | import io.github.freya022.botcommands.internal.components.LifetimeType 5 | import io.github.freya022.botcommands.internal.components.data.timeout.ComponentTimeout 6 | import kotlinx.datetime.Instant 7 | import kotlin.time.Duration 8 | 9 | internal class ComponentGroupData internal constructor( 10 | override val internalId: Int, 11 | override val lifetimeType: LifetimeType, 12 | override val expiresAt: Instant?, 13 | override val resetTimeoutOnUseDuration: Duration?, 14 | override val timeout: ComponentTimeout?, 15 | internal val componentIds: List, 16 | ): ComponentData { 17 | override val componentType: ComponentType 18 | get() = ComponentType.GROUP 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/data/timeout/ComponentTimeout.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.data.timeout 2 | 3 | internal sealed interface ComponentTimeout -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/data/timeout/EphemeralTimeout.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.data.timeout 2 | 3 | internal class EphemeralTimeout( 4 | val handler: suspend () -> Unit 5 | ) : ComponentTimeout -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/EphemeralComponentHandlers.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.handler 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.RequiresComponents 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.internal.components.EphemeralHandlers 6 | 7 | @BService 8 | @RequiresComponents 9 | internal class EphemeralComponentHandlers : EphemeralHandlers>() -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/handler/options/builder/ComponentHandlerOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.handler.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.core.options.builder.OptionBuilderImpl 4 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 5 | 6 | internal class ComponentHandlerOptionBuilderImpl( 7 | optionParameter: OptionParameter 8 | ) : OptionBuilderImpl(optionParameter) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/timeout/EphemeralTimeoutHandlers.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.timeout 2 | 3 | import io.github.freya022.botcommands.api.components.annotations.RequiresComponents 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.internal.components.EphemeralHandlers 6 | 7 | @BService 8 | @RequiresComponents 9 | internal class EphemeralTimeoutHandlers : EphemeralHandlers Unit>() -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/timeout/TimeoutHandlerContainer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.timeout 2 | 3 | internal interface TimeoutHandlerContainer { 4 | operator fun get(handlerName: String): TimeoutDescriptor<*>? 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/components/timeout/options/builder/TimeoutHandlerOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.components.timeout.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.core.options.builder.OptionBuilderImpl 4 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 5 | 6 | internal class TimeoutHandlerOptionBuilderImpl internal constructor( 7 | optionParameter: OptionParameter 8 | ) : OptionBuilderImpl(optionParameter) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/SpringBotCommandsConfiguration.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core 2 | 3 | import io.github.freya022.botcommands.api.core.config.JDAConfiguration 4 | import io.github.freya022.botcommands.internal.core.annotations.InternalComponentScan 5 | import io.github.freya022.botcommands.internal.core.config.BotCommandsCoreConfiguration 6 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan 7 | import org.springframework.context.annotation.Configuration 8 | 9 | @Configuration 10 | @InternalComponentScan( 11 | basePackages = [ 12 | "io.github.freya022.botcommands.api", 13 | "io.github.freya022.botcommands.internal", 14 | ] 15 | ) 16 | @ConfigurationPropertiesScan(basePackageClasses = [JDAConfiguration::class, BotCommandsCoreConfiguration::class]) 17 | internal open class SpringBotCommandsConfiguration -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/SpringBotCommandsInitializer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core 2 | 3 | import io.github.freya022.botcommands.internal.core.service.SpringBotCommandsBootstrap 4 | import org.springframework.beans.factory.getBean 5 | import org.springframework.boot.context.event.ApplicationReadyEvent 6 | import org.springframework.context.event.EventListener 7 | import org.springframework.stereotype.Component 8 | 9 | @Component 10 | internal data object SpringBotCommandsInitializer { 11 | @EventListener 12 | internal fun onAppReadyEvent(event: ApplicationReadyEvent) { 13 | val bootstrap = event.applicationContext.getBean() 14 | bootstrap.loadContext() 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/annotations/InternalComponentScan.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.annotations 2 | 3 | import org.springframework.context.annotation.ComponentScan 4 | import org.springframework.core.annotation.AliasFor 5 | 6 | @ComponentScan 7 | internal annotation class InternalComponentScan( 8 | @get:AliasFor(annotation = ComponentScan::class) 9 | vararg val basePackages: String 10 | ) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/config/ConfigDSL.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.config 2 | 3 | @DslMarker 4 | internal annotation class ConfigDSL -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/db/InternalDatabase.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.db 2 | 3 | import io.github.freya022.botcommands.api.core.db.Database 4 | import io.github.freya022.botcommands.api.core.db.annotations.RequiresDatabase 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import io.github.freya022.botcommands.api.core.service.annotations.IgnoreServiceTypes 7 | 8 | @BService 9 | @RequiresDatabase 10 | @IgnoreServiceTypes(Database::class) 11 | internal class InternalDatabase internal constructor(private val database: Database) : Database by database { 12 | override suspend fun fetchConnection(readOnly: Boolean) = database.fetchConnection().also { 13 | it.schema = "bc" 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/entities/InputUserImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.entities 2 | 3 | import io.github.freya022.botcommands.api.core.entities.InputUser 4 | import net.dv8tion.jda.api.entities.Member 5 | import net.dv8tion.jda.api.entities.User 6 | 7 | internal class InputUserImpl internal constructor( 8 | private val user: User, 9 | override val member: Member? 10 | ) : InputUser, User by user { 11 | constructor(member: Member) : this(member.user, member) 12 | constructor(user: User) : this(user, null) 13 | 14 | override fun toString(): String { 15 | return when { 16 | member != null -> "InputUser($member)" 17 | else -> "InputUser($user)" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/exceptions/InitializationException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.exceptions 2 | 3 | internal class InitializationException internal constructor(message: String, cause: Throwable) : Exception(message, cause) 4 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/exceptions/InternalException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.exceptions 2 | 3 | import io.github.freya022.botcommands.api.BCInfo 4 | import net.dv8tion.jda.api.JDAInfo 5 | 6 | internal class InternalException internal constructor( 7 | message: String, 8 | throwable: Throwable? = null, 9 | ) : RuntimeException(internalErrorMessage(message), throwable) 10 | 11 | internal fun getDiagnosticVersions() = "[ BC version: ${BCInfo.VERSION} | Current JDA version: ${JDAInfo.VERSION} ]" 12 | 13 | internal fun internalErrorMessage(message: String) = "$message, please report this to the devs. ${getDiagnosticVersions()}" -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/exceptions/ServiceException.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.exceptions 2 | 3 | import io.github.freya022.botcommands.api.core.service.ServiceError 4 | 5 | internal class ServiceException internal constructor( 6 | val serviceError: ServiceError 7 | ) : RuntimeException("\n${serviceError.toDetailedString()}") -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/hooks/DispatcherAwareCoroutineEventManager.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.hooks 2 | 3 | import dev.minn.jda.ktx.events.CoroutineEventManager 4 | import net.dv8tion.jda.api.events.GenericEvent 5 | 6 | internal class DispatcherAwareCoroutineEventManager internal constructor( 7 | originalCoroutineEventManager: CoroutineEventManager, 8 | private val eventDispatcher: EventDispatcherImpl, 9 | ) : CoroutineEventManager(originalCoroutineEventManager, originalCoroutineEventManager.timeout) { 10 | 11 | override fun handle(event: GenericEvent) { 12 | eventDispatcher.onEvent(event) 13 | super.handle(event) // Still let users use their own registered event listeners 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/AbstractGeneratedOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options 2 | 3 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 4 | 5 | internal abstract class AbstractGeneratedOption( 6 | optionParameter: OptionParameter 7 | ) : OptionImpl(optionParameter, OptionType.GENERATED) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/OptionType.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options 2 | 3 | import io.github.freya022.botcommands.api.core.utils.simpleNestedName 4 | 5 | internal enum class OptionType { 6 | OPTION, 7 | CUSTOM, 8 | CONSTANT, //TODO 9 | SERVICE, 10 | GENERATED; 11 | 12 | override fun toString(): String { 13 | return "${javaClass.simpleNestedName}#$name" 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/builder/AbstractGeneratedOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options.builder 2 | 3 | import io.github.freya022.botcommands.api.parameters.AggregatedParameter 4 | import io.github.freya022.botcommands.internal.core.options.AbstractGeneratedOption 5 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 6 | 7 | internal abstract class AbstractGeneratedOptionBuilderImpl( 8 | optionParameter: OptionParameter 9 | ) : OptionBuilderImpl(optionParameter) { 10 | internal abstract fun toGeneratedOption(parent: AggregatedParameter): AbstractGeneratedOption 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/builder/CustomOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 4 | 5 | internal class CustomOptionBuilderImpl internal constructor(optionParameter: OptionParameter) : OptionBuilderImpl(optionParameter) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/builder/OptionAggregateBuilderContainerMixin.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilder 4 | import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilderContainer 5 | 6 | internal interface OptionAggregateBuilderContainerMixin> : OptionAggregateBuilderContainer { 7 | val optionAggregateBuilders: Map 8 | 9 | fun hasVararg(): Boolean 10 | 11 | fun selfAggregate(declaredName: String, block: T.() -> Unit) 12 | 13 | fun varargAggregate(declaredName: String, block: T.() -> Unit) 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/builder/OptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options.builder 2 | 3 | import io.github.freya022.botcommands.api.core.options.builder.OptionBuilder 4 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 5 | 6 | internal abstract class OptionBuilderImpl internal constructor( 7 | /** 8 | * Declared name is not unique! (varargs, for example) 9 | */ 10 | internal val optionParameter: OptionParameter 11 | ) : OptionBuilder { 12 | internal val owner = optionParameter.typeCheckingFunction 13 | 14 | /** 15 | * **Note:** Could be an array parameter! In which case this parameter could be repeated on multiple options 16 | */ 17 | internal val parameter = optionParameter.typeCheckingParameter 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/options/builder/ServiceOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 4 | 5 | internal class ServiceOptionBuilderImpl internal constructor(optionParameter: OptionParameter) : OptionBuilderImpl(optionParameter) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/reflection/Function.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.reflection 2 | 3 | import io.github.freya022.botcommands.internal.utils.ReflectionUtils.reflectReference 4 | import kotlin.reflect.KFunction 5 | 6 | internal sealed class Function(boundFunction: KFunction) { 7 | internal val kFunction = boundFunction.reflectReference() 8 | internal val parametersSize = kFunction.parameters.size 9 | 10 | override fun equals(other: Any?): Boolean { 11 | if (this === other) return true 12 | if (javaClass != other?.javaClass) return false 13 | 14 | other as Function<*> 15 | 16 | return kFunction == other.kFunction 17 | } 18 | 19 | override fun hashCode() = kFunction.hashCode() 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/service/BotCommandsBootstrap.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.service 2 | 3 | import io.github.classgraph.ClassInfo 4 | import io.github.classgraph.MethodInfo 5 | import io.github.freya022.botcommands.api.core.service.ClassGraphProcessor 6 | import io.github.freya022.botcommands.api.core.service.ServiceContainer 7 | 8 | internal interface BotCommandsBootstrap { 9 | val classGraphProcessors: Set 10 | val serviceContainer: ServiceContainer 11 | 12 | fun isService(classInfo: ClassInfo): Boolean 13 | fun isServiceFactory(methodInfo: MethodInfo): Boolean 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/service/DefaultInjectionCondition.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.service 2 | 3 | import org.springframework.context.annotation.Condition 4 | import org.springframework.context.annotation.ConditionContext 5 | import org.springframework.core.type.AnnotatedTypeMetadata 6 | 7 | internal class DefaultInjectionCondition : Condition { 8 | override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata): Boolean { 9 | return false 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/service/annotations/HardcodedCondition.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.service.annotations 2 | 3 | @Target(AnnotationTarget.ANNOTATION_CLASS) 4 | internal annotation class HardcodedCondition -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/service/annotations/RequiresDefaultInjection.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.service.annotations 2 | 3 | import io.github.freya022.botcommands.internal.core.service.DefaultInjectionCondition 4 | import org.springframework.context.annotation.Conditional 5 | 6 | /** 7 | * Makes a service disabled when using Spring 8 | */ 9 | @Conditional(DefaultInjectionCondition::class) 10 | internal annotation class RequiresDefaultInjection -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/core/waiter/WaitingEvent.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.core.waiter 2 | 3 | import io.github.freya022.botcommands.api.core.waiter.CompletedFutureEvent 4 | import net.dv8tion.jda.api.events.Event 5 | import java.util.concurrent.CompletableFuture 6 | import java.util.function.Consumer 7 | import java.util.function.Predicate 8 | import kotlin.time.Duration 9 | 10 | internal class WaitingEvent internal constructor( 11 | val eventType: Class, 12 | val preconditions: List>, 13 | val onComplete: CompletedFutureEvent?, 14 | val onSuccess: Consumer?, 15 | val onTimeout: Runnable?, 16 | val onCancelled: Runnable?, 17 | val timeout: Duration? 18 | ) { 19 | val completableFuture = CompletableFuture() 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/emojis/AppEmojiContainerData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.emojis 2 | 3 | import io.github.freya022.botcommands.api.emojis.annotations.AppEmojiContainer 4 | import kotlin.reflect.KClass 5 | 6 | internal class AppEmojiContainerData( 7 | val clazz: KClass<*>, 8 | val annotation: AppEmojiContainer 9 | ) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/localization/LocalizableArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.localization 2 | 3 | /** 4 | * Marker interface, **do not implement.** 5 | */ 6 | interface LocalizableArgument -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/localization/LocalizationImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.localization 2 | 3 | import io.github.freya022.botcommands.api.localization.Localization 4 | import io.github.freya022.botcommands.api.localization.LocalizationMap 5 | 6 | internal class LocalizationImpl internal constructor(private val bundle: LocalizationMap) : Localization, LocalizationMap by bundle 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/localization/RawArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.localization 2 | 3 | internal class RawArgument internal constructor(private val string: String) : LocalizableArgument { 4 | fun get() = string 5 | 6 | override fun toString(): String { 7 | return "RawArgument(string='$string')" 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/localization/SimpleArgument.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.localization 2 | 3 | import io.github.freya022.botcommands.api.localization.arguments.FormattableArgument 4 | 5 | internal class SimpleArgument internal constructor(override val argumentName: String) : FormattableArgument { 6 | override fun format(obj: Any): String = obj.toString() 7 | 8 | override fun toString(): String { 9 | return "SimpleArgument(argumentName='$argumentName')" 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/EphemeralModalHandlerData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import io.github.freya022.botcommands.api.modals.ModalEvent 4 | 5 | internal class EphemeralModalHandlerData(val handler: suspend (ModalEvent) -> Unit) : IModalHandlerData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/IModalHandlerData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | internal sealed interface IModalHandlerData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/IPartialModalData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import gnu.trove.map.TLongObjectMap 4 | 5 | internal interface IPartialModalData { 6 | val handlerData: IModalHandlerData? 7 | val inputDataMap: TLongObjectMap 8 | val timeoutInfo: ModalTimeoutInfo? 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/InputData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | internal class InputData(val inputName: String) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalDSL.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | @DslMarker 4 | internal annotation class ModalDSL 5 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import io.github.freya022.botcommands.api.modals.ModalEvent 4 | import kotlinx.coroutines.CancellableContinuation 5 | import kotlinx.coroutines.Job 6 | import kotlinx.coroutines.cancel 7 | 8 | internal class ModalData( 9 | partialModalData: PartialModalData, 10 | private val timeoutJob: Job? 11 | ) : IPartialModalData by partialModalData { 12 | val continuations: MutableList> = arrayListOf() 13 | 14 | fun cancelTimeout() { 15 | timeoutJob?.cancel("Cancelled by modal usage") 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalTimeoutInfo.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import kotlin.time.Duration 4 | 5 | internal class ModalTimeoutInfo internal constructor(val timeout: Duration, val onTimeout: (suspend () -> Unit)?) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/ModalsImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BService 4 | import io.github.freya022.botcommands.api.modals.Modals 5 | import io.github.freya022.botcommands.api.modals.TextInputBuilder 6 | import io.github.freya022.botcommands.api.modals.annotations.RequiresModals 7 | import net.dv8tion.jda.api.interactions.components.text.TextInputStyle 8 | 9 | @BService 10 | @RequiresModals 11 | internal class ModalsImpl(private val modalMaps: ModalMaps) : Modals { 12 | override fun create(title: String): ModalBuilderImpl { 13 | return ModalBuilderImpl(this, modalMaps, title) 14 | } 15 | 16 | override fun createTextInput(inputName: String, label: String, style: TextInputStyle): TextInputBuilder { 17 | return TextInputBuilderImpl(modalMaps, inputName, label, style) 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/PartialModalData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import gnu.trove.map.TLongObjectMap 4 | 5 | internal open class PartialModalData( 6 | override val handlerData: IModalHandlerData?, 7 | override val inputDataMap: TLongObjectMap, 8 | override val timeoutInfo: ModalTimeoutInfo? 9 | ) : IPartialModalData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/PersistentModalHandlerData.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | internal class PersistentModalHandlerData(val handlerName: String, val userData: List) : IModalHandlerData -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/TextInputBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals 2 | 3 | import io.github.freya022.botcommands.api.modals.TextInputBuilder 4 | import net.dv8tion.jda.api.interactions.components.text.TextInput 5 | import net.dv8tion.jda.api.interactions.components.text.TextInputStyle 6 | 7 | internal class TextInputBuilderImpl internal constructor( 8 | private val modalMaps: ModalMaps, 9 | private val inputName: String, 10 | label: String?, 11 | style: TextInputStyle? 12 | ) : TextInputBuilder(label, style) { 13 | override fun build(): TextInput { 14 | internetSetId(modalMaps.insertInput(InputData(inputName))) 15 | 16 | return jdaBuild() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/options/ModalHandlerDataOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals.options 2 | 3 | import io.github.freya022.botcommands.internal.core.options.AbstractGeneratedOption 4 | import io.github.freya022.botcommands.internal.modals.options.builder.ModalHandlerDataOptionBuilderImpl 5 | 6 | internal class ModalHandlerDataOption internal constructor( 7 | override val parent: ModalHandlerParameterImpl, 8 | optionBuilder: ModalHandlerDataOptionBuilderImpl 9 | ) : AbstractGeneratedOption(optionBuilder.optionParameter) { 10 | 11 | override val executable get() = parent.executable 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/options/ModalHandlerInputOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals.options 2 | 3 | import io.github.freya022.botcommands.api.core.utils.findAnnotationRecursive 4 | import io.github.freya022.botcommands.api.modals.annotations.ModalInput 5 | import io.github.freya022.botcommands.api.parameters.resolvers.ModalParameterResolver 6 | import io.github.freya022.botcommands.internal.modals.options.builder.ModalHandlerInputOptionBuilderImpl 7 | 8 | internal class ModalHandlerInputOption( 9 | override val parent: ModalHandlerParameterImpl, 10 | optionBuilder: ModalHandlerInputOptionBuilderImpl, 11 | val resolver: ModalParameterResolver<*, *> 12 | ) : ModalHandlerOption(optionBuilder) { 13 | 14 | override val executable get() = parent.executable 15 | 16 | val inputName: String = kParameter.findAnnotationRecursive()!!.name 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/options/ModalHandlerOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals.options 2 | 3 | import io.github.freya022.botcommands.api.modals.options.ModalOption 4 | import io.github.freya022.botcommands.internal.core.options.OptionImpl 5 | import io.github.freya022.botcommands.internal.core.options.OptionType 6 | import io.github.freya022.botcommands.internal.core.options.builder.OptionBuilderImpl 7 | 8 | internal abstract class ModalHandlerOption internal constructor( 9 | optionBuilder: OptionBuilderImpl 10 | ) : OptionImpl(optionBuilder.optionParameter, OptionType.OPTION), 11 | ModalOption -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/options/builder/ModalHandlerDataOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals.options.builder 2 | 3 | import io.github.freya022.botcommands.api.parameters.AggregatedParameter 4 | import io.github.freya022.botcommands.internal.core.options.builder.AbstractGeneratedOptionBuilderImpl 5 | import io.github.freya022.botcommands.internal.modals.options.ModalHandlerDataOption 6 | import io.github.freya022.botcommands.internal.modals.options.ModalHandlerParameterImpl 7 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 8 | 9 | internal class ModalHandlerDataOptionBuilderImpl( 10 | optionParameter: OptionParameter 11 | ) : AbstractGeneratedOptionBuilderImpl(optionParameter) { 12 | override fun toGeneratedOption(parent: AggregatedParameter) = 13 | ModalHandlerDataOption(parent as ModalHandlerParameterImpl, this) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/modals/options/builder/ModalHandlerInputOptionBuilderImpl.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.modals.options.builder 2 | 3 | import io.github.freya022.botcommands.internal.core.options.builder.OptionBuilderImpl 4 | import io.github.freya022.botcommands.internal.parameters.OptionParameter 5 | 6 | internal class ModalHandlerInputOptionBuilderImpl(optionParameter: OptionParameter) : OptionBuilderImpl(optionParameter) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/CustomMethodOption.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters 2 | 3 | import io.github.freya022.botcommands.api.parameters.AggregatedParameter 4 | import io.github.freya022.botcommands.api.parameters.resolvers.ICustomResolver 5 | import io.github.freya022.botcommands.internal.core.options.OptionImpl 6 | import io.github.freya022.botcommands.internal.core.options.OptionType 7 | 8 | internal class CustomMethodOption internal constructor( 9 | override val parent: AggregatedParameter, 10 | optionParameter: OptionParameter, 11 | val resolver: ICustomResolver<*, *> 12 | ) : OptionImpl(optionParameter, OptionType.CUSTOM) { 13 | 14 | override val executable get() = parent.executable 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/InputUserResolver.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.core.entities.InputUser 5 | import io.github.freya022.botcommands.api.core.service.annotations.Resolver 6 | import io.github.freya022.botcommands.internal.core.entities.InputUserImpl 7 | import net.dv8tion.jda.api.entities.Member 8 | import net.dv8tion.jda.api.entities.User 9 | 10 | @Resolver 11 | internal class InputUserResolver internal constructor( 12 | context: BContext 13 | ) : AbstractUserSnowflakeResolver(context, InputUser::class) { 14 | override fun transformEntities(user: User, member: Member?): InputUser = InputUserImpl(user, member) 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/RoleResolverFactoryProvider.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers 2 | 3 | import io.github.freya022.botcommands.api.commands.application.checkGuildOnly 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.api.core.service.annotations.ResolverFactory 6 | import io.github.freya022.botcommands.api.parameters.resolverFactory 7 | import net.dv8tion.jda.api.entities.Role 8 | 9 | @BService 10 | internal data object RoleResolverFactoryProvider { 11 | @ResolverFactory 12 | internal fun roleResolverFactory() = resolverFactory { request -> 13 | request.checkGuildOnly(Role::class) 14 | RoleResolver() 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/UserResolver.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers 2 | 3 | import io.github.freya022.botcommands.api.core.BContext 4 | import io.github.freya022.botcommands.api.core.service.annotations.Resolver 5 | import net.dv8tion.jda.api.entities.Member 6 | import net.dv8tion.jda.api.entities.User 7 | 8 | @Resolver 9 | internal class UserResolver internal constructor( 10 | context: BContext 11 | ): AbstractUserSnowflakeResolver(context, User::class) { 12 | override fun transformEntities(user: User, member: Member?): User = user 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/exceptions/MissingResolverAnnotation.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers.exceptions 2 | 3 | internal class MissingResolverAnnotation internal constructor( 4 | message: String 5 | ) : IllegalStateException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/exceptions/MissingResolverFactoryAnnotation.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers.exceptions 2 | 3 | internal class MissingResolverFactoryAnnotation internal constructor( 4 | message: String 5 | ) : IllegalStateException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/exceptions/MissingResolverFactorySuperclass.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers.exceptions 2 | 3 | internal class MissingResolverFactorySuperclass internal constructor( 4 | message: String 5 | ) : IllegalStateException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/parameters/resolvers/exceptions/MissingResolverSuperclass.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.parameters.resolvers.exceptions 2 | 3 | internal class MissingResolverSuperclass internal constructor( 4 | message: String 5 | ) : IllegalStateException(message) -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/utils/Checks.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.utils 2 | 3 | import kotlin.time.Duration 4 | 5 | internal object Checks { 6 | internal fun checkFinite(duration: Duration, name: String) { 7 | require(duration.isFinite() && duration.isPositive()) { 8 | "The $name must be finite and positive" 9 | } 10 | } 11 | 12 | internal fun checkFitInt(duration: Duration, name: String) { 13 | require(duration.inWholeMilliseconds in Int.MIN_VALUE..Int.MAX_VALUE) { 14 | "The $name must be finite and positive" 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/utils/Collections.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.utils 2 | 3 | import gnu.trove.TIntCollection 4 | 5 | internal inline fun TIntCollection.any(block: (Int) -> Boolean): Boolean { 6 | for (it in this) 7 | if (block(it)) 8 | return true 9 | return false 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/utils/References.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.utils 2 | 3 | import io.github.freya022.botcommands.api.core.utils.simpleNestedName 4 | import kotlin.jvm.internal.CallableReference 5 | import kotlin.reflect.KClass 6 | import kotlin.reflect.KProperty 7 | 8 | @PublishedApi 9 | internal val KProperty<*>.reference: String 10 | get() { 11 | val callableReference = (this as? CallableReference) 12 | ?: throwInternal("Referenced field doesn't seem to be compiler generated, exact type: ${this::class}") 13 | return (callableReference.owner as KClass<*>).simpleNestedName + "." + this.name 14 | } 15 | 16 | internal inline fun annotationRef(): String = "@${classRef()}" 17 | 18 | internal inline fun classRef(): String = A::class.java.simpleNestedName -------------------------------------------------------------------------------- /src/main/kotlin/io/github/freya022/botcommands/internal/utils/Signatures.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.internal.utils 2 | 3 | import io.github.freya022.botcommands.api.core.utils.getSignature 4 | import kotlin.reflect.KFunction 5 | 6 | internal val KFunction<*>.shortSignatureNoSrc: String 7 | get() = getSignature(returnType = true, source = false) 8 | 9 | internal val KFunction<*>.shortSignature: String 10 | get() = getSignature(returnType = true) -------------------------------------------------------------------------------- /src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [], 3 | "properties": [], 4 | "hints": [] 5 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationListener=io.github.freya022.botcommands.internal.core.service.SpringBotCommandsVersionChecker -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | io.github.freya022.botcommands.autoconfigure.BotCommandsAutoConfiguration -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2023.09.23__Component_rate_limit.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 2nd migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | set schema 'bc'; 5 | 6 | update bc_version 7 | set version = '3.0.0-alpha.6' 8 | where one_row = true; 9 | 10 | alter table bc_component 11 | add column rate_limit_group text null; -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2023.10.24__Component_filters.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 3rd migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | set schema 'bc'; 5 | 6 | update bc_version 7 | set version = '3.0.0-alpha.8' 8 | where one_row = true; 9 | 10 | alter table bc_component 11 | add column filters text array; 12 | 13 | update bc_component set filters = '{}'; 14 | 15 | alter table bc_component alter filters set not null; -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2024.08.24__Reset_timeout_on_use.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 5th migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | SET SCHEMA 'bc'; 5 | 6 | UPDATE bc_version 7 | SET version = '3.0.0-alpha.19' 8 | WHERE one_row = true; 9 | 10 | -- Add column 11 | ALTER TABLE bc_component 12 | ADD COLUMN reset_timeout_on_use_duration_ms INT NULL DEFAULT NULL; 13 | -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2024.08.27__Application_commands_cache.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 6th migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | SET SCHEMA 'bc'; 5 | 6 | UPDATE bc_version 7 | SET version = '3.0.0-alpha.19' 8 | WHERE one_row = true; 9 | 10 | CREATE TABLE application_commands_cache 11 | ( 12 | application_id BIGINT NOT NULL, 13 | guild_id BIGINT NULL, 14 | data TEXT NOT NULL, 15 | metadata TEXT NOT NULL, 16 | 17 | UNIQUE (application_id, guild_id) 18 | ); 19 | -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2024.09.25__Component_rate_limit_reference.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 7th migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | SET SCHEMA 'bc'; 5 | 6 | UPDATE bc_version 7 | SET version = '3.0.0-alpha.19' 8 | WHERE one_row = true; 9 | 10 | ALTER TABLE bc_component 11 | ADD COLUMN rate_limit_discriminator TEXT NULL; 12 | -------------------------------------------------------------------------------- /src/main/resources/bc_database_scripts/V3.0.0.2025.02.16__Component_data_serialization.sql: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 8th migration script for BotCommands ------------------------------------------------------ 2 | ---------------------------------- Make sure to run the previous scripts (chronological order) before this one ----------------------------------- 3 | 4 | SET SCHEMA 'bc'; 5 | 6 | UPDATE bc_version 7 | SET version = '3.0.0-beta.1' 8 | WHERE one_row = true; 9 | 10 | ALTER TABLE bc_persistent_handler 11 | ALTER COLUMN user_data SET DATA TYPE bytea array USING cast(user_data as bytea array); 12 | 13 | ALTER TABLE bc_persistent_timeout 14 | ALTER COLUMN user_data SET DATA TYPE bytea array USING cast(user_data as bytea array); 15 | -------------------------------------------------------------------------------- /src/test/README.md: -------------------------------------------------------------------------------- 1 | # Test folder 2 | 3 | This is not a unit test folder, at least for the moment. 4 | 5 | **Do not take this code seriously, nor as an example, it is solely to test library functionalities as time goes by** -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/framework/FakeBot.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.framework 2 | 3 | import io.github.freya022.botcommands.api.core.JDAService 4 | import io.github.freya022.botcommands.api.core.events.BReadyEvent 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import net.dv8tion.jda.api.hooks.IEventManager 7 | import net.dv8tion.jda.api.requests.GatewayIntent 8 | import net.dv8tion.jda.api.utils.cache.CacheFlag 9 | 10 | @BService 11 | class FakeBot : JDAService() { 12 | override val intents: Set 13 | get() = emptySet() 14 | override val cacheFlags: Set 15 | get() = emptySet() 16 | 17 | override fun createJDA(event: BReadyEvent, eventManager: IEventManager) {} 18 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/framework/H2MigrationTests.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.framework 2 | 3 | import org.junit.jupiter.api.Test 4 | 5 | class H2MigrationTests { 6 | @Test 7 | fun `Test migration scripts on H2`() { 8 | TestH2() 9 | } 10 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/othertests/CollectionTypeTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.othertests 2 | 3 | import io.github.freya022.botcommands.internal.utils.ReflectionUtils.collectionElementType 4 | import net.dv8tion.jda.api.entities.Member 5 | import net.dv8tion.jda.api.entities.User 6 | 7 | class MyCollection(collection: Collection) : Collection by collection 8 | 9 | fun test(): Collection = throw UnsupportedOperationException() 10 | fun testCustom(): MyCollection = throw UnsupportedOperationException() 11 | 12 | fun main() { 13 | println(::test.returnType.collectionElementType) 14 | println(::testCustom.returnType.collectionElementType) 15 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/CoroutineEventManagerSupplier.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test 2 | 3 | import dev.minn.jda.ktx.events.CoroutineEventManager 4 | import io.github.freya022.botcommands.api.core.ICoroutineEventManagerSupplier 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import io.github.freya022.botcommands.api.core.utils.namedDefaultScope 7 | 8 | @BService 9 | object CoroutineEventManagerSupplier : ICoroutineEventManagerSupplier { 10 | override fun get(): CoroutineEventManager { 11 | val scope = namedDefaultScope("$botName Coroutine", 4) 12 | return CoroutineEventManager(scope) 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/CustomObject.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test 2 | 3 | class CustomObject { 4 | override fun toString(): String = "NotACustomObject@${hashCode()}" 5 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/MyAutocompleteTransformer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test 2 | 3 | import io.github.freya022.botcommands.api.commands.application.slash.autocomplete.AutocompleteTransformer 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import net.dv8tion.jda.api.interactions.commands.Command 6 | 7 | @BService 8 | class MyAutocompleteTransformer : AutocompleteTransformer { 9 | override val elementType: Class 10 | get() = CustomObject::class.java 11 | 12 | override fun apply(e: CustomObject) = Command.Choice(e.toString(), e.toString()) 13 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/MyGlobalExceptionHandler.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test 2 | 3 | import io.github.freya022.botcommands.api.core.GlobalExceptionHandlerAdapter 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.test.switches.TestService 6 | import io.github.oshai.kotlinlogging.KotlinLogging 7 | import net.dv8tion.jda.api.events.Event 8 | 9 | @BService 10 | @TestService 11 | class MyGlobalExceptionHandler : GlobalExceptionHandlerAdapter() { 12 | private val logger = KotlinLogging.logger { } 13 | 14 | override fun handle(event: Event?, throwable: Throwable) { 15 | logger.error(throwable) { "Custom exception handling" } 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/MyHelpBuilderConsumer.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test 2 | 3 | import io.github.freya022.botcommands.api.commands.text.HelpBuilderConsumer 4 | import io.github.freya022.botcommands.api.commands.text.TextCommandInfo 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import io.github.freya022.botcommands.test.switches.TestService 7 | import net.dv8tion.jda.api.EmbedBuilder 8 | 9 | @BService 10 | @TestService 11 | class MyHelpBuilderConsumer : HelpBuilderConsumer { 12 | override fun accept(builder: EmbedBuilder, isGlobal: Boolean, commandInfo: TextCommandInfo?) { 13 | builder.addField("A field name", "Test for ${javaClass.simpleName}", false) 14 | } 15 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/commands/text/TextMentionable.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.commands.text 2 | 3 | import dev.minn.jda.ktx.coroutines.await 4 | import io.github.freya022.botcommands.api.commands.annotations.Command 5 | import io.github.freya022.botcommands.api.commands.text.BaseCommandEvent 6 | import io.github.freya022.botcommands.api.commands.text.TextCommand 7 | import io.github.freya022.botcommands.api.commands.text.annotations.JDATextCommandVariation 8 | import io.github.freya022.botcommands.api.commands.text.annotations.TextOption 9 | import net.dv8tion.jda.api.entities.IMentionable 10 | 11 | @Command 12 | class TextMentionable : TextCommand() { 13 | @JDATextCommandVariation(path = ["mentionable"]) 14 | suspend fun onTextMentionable(event: BaseCommandEvent, @TextOption mentionable: IMentionable) { 15 | event.respond(mentionable.id).await() 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/config/Data.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.config 2 | 3 | import java.io.FileNotFoundException 4 | import java.nio.file.Path 5 | import kotlin.io.path.absolutePathString 6 | import kotlin.io.path.notExists 7 | 8 | object Data { 9 | /** 10 | * Where your bot can write data if needed 11 | */ 12 | val folder: Path = Environment.folder.resolve(if (Environment.isDev) "dev-data" else "data") 13 | 14 | /** 15 | * Checks whether the path exists, throwing if not. 16 | */ 17 | private fun Path.validatedPath(desc: String): Path = this.also { 18 | if (it.notExists()) 19 | throw FileNotFoundException("$desc at ${it.absolutePathString()} does not exist.") 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/config/Environment.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.config 2 | 3 | import java.nio.file.Path 4 | import kotlin.io.path.Path 5 | import kotlin.io.path.exists 6 | 7 | object Environment { 8 | /** 9 | * The folder where the data and configuration directories reside. 10 | */ 11 | val folder: Path = Path("test-files", "test") 12 | 13 | /** 14 | * The mode is determined by checking if the 15 | * `dev-config` directory exists in the current directory. 16 | */ 17 | val isDev: Boolean = folder.resolve("dev-config").exists() 18 | 19 | val configFolder: Path = 20 | folder.resolve(if (isDev) "dev-config" else "config") 21 | val logbackConfigPath: Path = configFolder.resolve(if (isDev) "logback-test.xml" else "logback.xml") 22 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/listeners/DisabledTextListener.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.listeners 2 | 3 | import io.github.freya022.botcommands.api.core.annotations.BEventListener 4 | import io.github.freya022.botcommands.api.core.service.annotations.BService 5 | import io.github.freya022.botcommands.api.core.utils.simpleNestedName 6 | import io.github.freya022.botcommands.test.switches.TestService 7 | import io.github.oshai.kotlinlogging.KotlinLogging 8 | import net.dv8tion.jda.api.events.message.MessageReceivedEvent 9 | 10 | private val logger = KotlinLogging.logger { } 11 | 12 | @BService 13 | @TestService 14 | class DisabledTextListener { 15 | @BEventListener 16 | fun onMessage(event: MessageReceivedEvent) { 17 | logger.trace { "Received message in ${this.javaClass.simpleNestedName}" } 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/resolvers/CustomObjectResolver.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.resolvers 2 | 3 | import io.github.freya022.botcommands.api.core.options.Option 4 | import io.github.freya022.botcommands.api.core.service.annotations.Resolver 5 | import io.github.freya022.botcommands.api.parameters.ClassParameterResolver 6 | import io.github.freya022.botcommands.api.parameters.resolvers.ICustomResolver 7 | import io.github.freya022.botcommands.test.CustomObject 8 | import net.dv8tion.jda.api.events.Event 9 | 10 | @Resolver 11 | class CustomObjectResolver : 12 | ClassParameterResolver(CustomObject::class), 13 | ICustomResolver { 14 | 15 | override suspend fun resolveSuspend(option: Option, event: Event): CustomObject { 16 | return CustomObject() 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/DisabledFactoriesByClass.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | import io.github.freya022.botcommands.api.core.service.ConditionalServiceChecker 4 | import io.github.freya022.botcommands.api.core.service.ServiceContainer 5 | import io.github.freya022.botcommands.api.core.service.annotations.BService 6 | import io.github.freya022.botcommands.api.core.service.annotations.ConditionalService 7 | import net.dv8tion.jda.api.JDA 8 | 9 | @BService 10 | @ConditionalService(DisabledFactoriesByClass.Companion::class) 11 | class DisabledFactoriesByClass { 12 | @BService 13 | fun jda(): JDA = throw AssertionError() 14 | 15 | companion object : ConditionalServiceChecker { 16 | override fun checkServiceAvailability(serviceContainer: ServiceContainer, checkedClass: Class<*>): String { 17 | return "Disabled class and factories" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/MyDevService.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BService 4 | import io.github.freya022.botcommands.test.services.annotations.RequireProfile 5 | import io.github.oshai.kotlinlogging.KotlinLogging 6 | 7 | private val logger = KotlinLogging.logger { } 8 | 9 | @BService 10 | @RequireProfile(Profile.DEV) 11 | class MyDevService { 12 | init { 13 | logger.trace { "Enabled dev service" } 14 | } 15 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/NamedService.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BService 4 | import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService 5 | import io.github.freya022.botcommands.internal.core.service.annotations.RequiresDefaultInjection 6 | 7 | @InterfacedService(acceptMultiple = true) 8 | interface INamedService 9 | 10 | @BService(name = "modifiedNamedService") 11 | @RequiresDefaultInjection 12 | class NamedService1 : INamedService 13 | 14 | @BService(name = "normalNamedService") 15 | @RequiresDefaultInjection 16 | class NamedService2 : INamedService -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/NonUniqueCommandFactoryTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.BConfiguration 4 | 5 | @BConfiguration 6 | object NonUniqueCommandFactoryTest { 7 | // Uncomment to throw 8 | // @io.github.freya022.botcommands.api.core.service.annotations.BService 9 | // fun command1() = io.github.freya022.botcommands.test.commands.slash.SlashCooldown() 10 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/Profile.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | enum class Profile { 4 | PROD, 5 | DEV 6 | } -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/UnusedInterfacedService.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.InterfacedService 4 | 5 | // Must not be implemented 6 | @InterfacedService(acceptMultiple = false) 7 | internal sealed interface UnusedInterfacedService -------------------------------------------------------------------------------- /src/test/kotlin/io/github/freya022/botcommands/test/services/annotations/RequireProfile.kt: -------------------------------------------------------------------------------- 1 | package io.github.freya022.botcommands.test.services.annotations 2 | 3 | import io.github.freya022.botcommands.api.core.service.annotations.Condition 4 | import io.github.freya022.botcommands.test.services.Profile 5 | import io.github.freya022.botcommands.test.services.ProfileChecker 6 | 7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER) 8 | @Condition(ProfileChecker::class, fail = false) 9 | annotation class RequireProfile(val profile: Profile) 10 | -------------------------------------------------------------------------------- /src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.devtools.livereload.enabled=false 2 | 3 | botcommands.core.disableExceptionsInDMs=true 4 | botcommands.database.queryLogThreshold=250ms 5 | botcommands.database.dumpLongTransactions=true 6 | botcommands.components.enable=true 7 | botcommands.text.usePingAsPrefix=true 8 | botcommands.application.cache.checkOnline=true 9 | botcommands.application.localizations.MyCommands=english_us,english_uk,french 10 | botcommands.localization.responseBundles=Test 11 | botcommands.text.dmClosedEmoji=x -------------------------------------------------------------------------------- /src/test/resources/bc_localization/DefaultMessages.json: -------------------------------------------------------------------------------- 1 | { 2 | "null.component.type.error.message": "Component go bruh :skull:" 3 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/DefaultMessages_fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "null.component.type.error.message": "Ce composant n'est plus utilisable" 3 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/MyCommands.json: -------------------------------------------------------------------------------- 1 | { 2 | "localization": { 3 | "description": "Inferred command description", 4 | "options": { 5 | "localization_opt.description": "Inferred option description" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/MyCommands_en_GB.json: -------------------------------------------------------------------------------- 1 | { 2 | "localization.name": "localization_en_gb", 3 | "localization.description": "localization_desc_en_gb" 4 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/MyCommands_en_US.json: -------------------------------------------------------------------------------- 1 | { 2 | "localization.name": "localization_en_us", 3 | "localization.description": "localization_desc_en_us" 4 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/MyCommands_fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "localization.name": "localization_fr", 3 | "localization.description": "localization_desc_fr" 4 | } -------------------------------------------------------------------------------- /src/test/resources/bc_localization/Test.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": { 3 | "ban": { 4 | "name": "ban", 5 | "description": "Bannis un utilisateur", 6 | "options": { 7 | "user": { 8 | "name": "utilisateur", 9 | "description": "Utilisateur a ban" 10 | }, 11 | "delDays": { 12 | "name": "sup_messages", 13 | "description": "Nb jours à supprimer" 14 | }, 15 | "reason": { 16 | "name": "raison", 17 | "description": "La raison" 18 | } 19 | } 20 | } 21 | }, 22 | "commands.localization.response": "There are {guild_users} {guild_users, choice, 0#users|1#user|1", 8 | "!" 9 | ], 10 | "testGuildIds": [], 11 | "databaseConfig": { 12 | "serverName": "localhost", 13 | "port": 5432, 14 | "name": "", 15 | "user": "", 16 | "password": "" 17 | } 18 | } -------------------------------------------------------------------------------- /test-files/test/config-template/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "", 3 | "ownerIds": [ 4 | 5 | ], 6 | "prefixes": [ 7 | "", 8 | "!" 9 | ], 10 | "testGuildIds": [], 11 | "testMode": false, 12 | "databaseConfig": { 13 | "serverName": "localhost", 14 | "port": 5432, 15 | "name": "", 16 | "user": "", 17 | "password": "" 18 | } 19 | } --------------------------------------------------------------------------------