diff --git a/src/examples/java/SlashBotExample.java b/src/examples/java/SlashBotExample.java index 0b993c758c..ba35517447 100644 --- a/src/examples/java/SlashBotExample.java +++ b/src/examples/java/SlashBotExample.java @@ -19,10 +19,14 @@ import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.Webhook; +import net.dv8tion.jda.api.entities.channel.attribute.IWebhookContainer; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.OptionMapping; @@ -34,6 +38,7 @@ import java.util.EnumSet; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import static net.dv8tion.jda.api.interactions.commands.OptionType.*; @@ -45,7 +50,7 @@ public static void main(String[] args) .addEventListeners(new SlashBotExample()) .build(); - // These commands might take a few minutes to be active after creation/update/delete + // You might need to reload your Discord client if you don't see the commands CommandListUpdateAction commands = jda.updateCommands(); // Moderation commands with required options @@ -56,27 +61,40 @@ public static void main(String[] args) .addOptions(new OptionData(INTEGER, "del_days", "Delete messages from the past days.") // This is optional .setRequiredRange(0, 7)) // Only allow values between 0 and 7 (inclusive) .addOptions(new OptionData(STRING, "reason", "The ban reason to use (default: Banned by )")) // optional reason - .setGuildOnly(true) // This way the command can only be executed from a guild, and not the DMs + .setContexts(InteractionContextType.GUILD) // This way the command can only be executed from a guild, and not the DMs .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.BAN_MEMBERS)) // Only members with the BAN_MEMBERS permission are going to see this command ); // Simple reply commands + commands.addCommands( + Commands.slash("echo", "Makes the bot reply to yourself") + .setContexts(InteractionContextType.ALL) // Allow the command to be used anywhere (Bot DMs, Guild, Friend DMs, Group DMs) + .setIntegrationTypes(IntegrationType.ALL) // Allow the command to be installed anywhere (Guilds, Users) + .addOption(STRING, "content", "What the bot should reply to yourself", true) // you can add required options like this too + ); + commands.addCommands( Commands.slash("say", "Makes the bot say what you tell it to") + .setContexts(InteractionContextType.ALL) // Allow the command to be used anywhere (Bot DMs, Guild, Friend DMs, Group DMs) + .setIntegrationTypes(IntegrationType.ALL) // Allow the command to be installed anywhere (Guilds, Users) .addOption(STRING, "content", "What the bot should say", true) // you can add required options like this too ); // Commands without any inputs commands.addCommands( Commands.slash("leave", "Make the bot leave the server") - .setGuildOnly(true) // this doesn't make sense in DMs + // The default integration types are GUILD_INSTALL. + // Can't use this in DMs, and in guilds the bot isn't in. + .setContexts(InteractionContextType.GUILD) .setDefaultPermissions(DefaultMemberPermissions.DISABLED) // only admins should be able to use this command. ); commands.addCommands( Commands.slash("prune", "Prune messages from this channel") .addOption(INTEGER, "amount", "How many messages to prune (Default 100)") // simple optional argument - .setGuildOnly(true) + // The default integration types are GUILD_INSTALL. + // Can't use this in DMs, and in guilds the bot isn't in. + .setContexts(InteractionContextType.GUILD) .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE)) ); @@ -98,6 +116,9 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) User user = event.getOption("user").getAsUser(); ban(event, user, member); break; + case "echo": + echo(event, event.getOption("content").getAsString()); // content is required so no null-check here + break; case "say": say(event, event.getOption("content").getAsString()); // content is required so no null-check here break; @@ -177,11 +198,78 @@ public void ban(SlashCommandInteractionEvent event, User user, Member member) .queue(); // execute the entire call chain } - public void say(SlashCommandInteractionEvent event, String content) + public void echo(SlashCommandInteractionEvent event, String content) { event.reply(content).queue(); // This requires no permissions! } + public void say(SlashCommandInteractionEvent event, String content) + { + event.deferReply().queue(); + + // To use a webhook, the bot needs to be in the guild, + // reply to the interaction in other cases (detached guilds, DMs, Group DMs). + tryUseWebhook( + event, + // If we can use a webhook + webhook -> + { + // Remove the bot thinking message + event.getHook().deleteOriginal().queue(); + + webhook.sendMessage(content) + .setUsername(event.getMember().getEffectiveName()) + .setAvatarUrl(event.getMember().getEffectiveAvatarUrl()) + .queue(); + }, + // Fallback + () -> event.getHook().sendMessage(content).queue() // This requires no permissions! + ); + } + + private void tryUseWebhook(SlashCommandInteractionEvent event, Consumer webhookCallback, Runnable noWebhookCallback) + { + // If the bot isn't in the guild, fallback to a normal reply + if (!event.hasFullGuild()) + { + noWebhookCallback.run(); + return; + } + + // In case the channel doesn't support webhooks, fallback to a normal reply + if (!(event.getGuildChannel() instanceof IWebhookContainer)) + { + noWebhookCallback.run(); + return; + } + + // If we don't have permissions to create a webhook, fallback to a normal reply + final IWebhookContainer webhookContainer = (IWebhookContainer) event.getGuildChannel(); + // Make sure to take the permission overrides into account by supplying the channel! + if (!event.getGuild().getSelfMember().hasPermission(webhookContainer, Permission.MANAGE_WEBHOOKS)) + { + noWebhookCallback.run(); + return; + } + + // We can use webhooks! Try to find an existing one, or create one + webhookContainer.retrieveWebhooks().queue(webhooks -> + { + // Try to find an existing webhook, one which we own + for (Webhook webhook : webhooks) + { + if (event.getJDA().getSelfUser().equals(webhook.getOwnerAsUser())) + { + webhookCallback.accept(webhook); + return; + } + } + + // No webhook found, create one and pass it to the callback + webhookContainer.createWebhook("/say webhook").queue(webhookCallback); + }); + } + public void leave(SlashCommandInteractionEvent event) { if (!event.getMember().hasPermission(Permission.KICK_MEMBERS)) diff --git a/src/main/java/net/dv8tion/jda/api/entities/ApplicationInfo.java b/src/main/java/net/dv8tion/jda/api/entities/ApplicationInfo.java index d7391675f0..5bb913f945 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/ApplicationInfo.java +++ b/src/main/java/net/dv8tion/jda/api/entities/ApplicationInfo.java @@ -18,16 +18,14 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.interactions.IntegrationType; import net.dv8tion.jda.api.utils.ImageProxy; import net.dv8tion.jda.internal.utils.Checks; import org.jetbrains.annotations.Unmodifiable; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumSet; -import java.util.List; +import java.util.*; /** * Represents a Discord Application from its bot's point of view. @@ -116,7 +114,7 @@ default ImageProxy getIcon() /** * Configures the required scopes applied to the {@link #getInviteUrl(Permission...)} and similar methods. - *
To use slash commands you must add {@code "applications.commands"} to these scopes. The scope {@code "bot"} is always applied. + *
The scope {@code "bot"} is always applied. * * @param scopes * The scopes to use with {@link #getInviteUrl(Permission...)} and the likes @@ -135,7 +133,7 @@ default ApplicationInfo setRequiredScopes(@Nonnull String... scopes) /** * Configures the required scopes applied to the {@link #getInviteUrl(Permission...)} and similar methods. - *
To use slash commands you must add {@code "applications.commands"} to these scopes. The scope {@code "bot"} is always applied. + *
The scope {@code "bot"} is always applied. * * @param scopes * The scopes to use with {@link #getInviteUrl(Permission...)} and the likes @@ -408,6 +406,56 @@ default EnumSet getFlags() */ long getFlagsRaw(); + /** + * The configurations for each {@link IntegrationType} set on the application. + * + * @return The configurations for each integration type + */ + @Nonnull + Map getIntegrationTypesConfig(); + + /** + * Configuration of a single {@link IntegrationType}. + * + * @see ApplicationInfo#getIntegrationTypesConfig() + */ + interface IntegrationTypeConfiguration + { + /** + * The OAuth2 install parameters for the default in-app authorization link. + *
When a user invites your application in the Discord app, these will be the parameters of the invite url. + * + * @return The OAuth2 install parameters for the default in-app authorization link + */ + @Nullable + InstallParameters getInstallParameters(); + } + + /** + * OAuth2 install parameter for the default in-app authorization link. + * + * @see IntegrationTypeConfiguration#getInstallParameters() + */ + interface InstallParameters + { + /** + * Gets the required scopes granted to the bot when invited. + * + * @return The required scopes granted to the bot when invited + */ + @Nonnull + List getScopes(); + + /** + * Gets the permissions your bot asks for when invited. + *
Note: Users can choose to disable permissions before and after inviting your bot. + * + * @return The permissions your bot asks for when invited + */ + @Nonnull + Set getPermissions(); + } + /** * Flag constants corresponding to the Discord Enum * diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 8c07ec5325..87a10c7987 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -36,6 +36,7 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; +import net.dv8tion.jda.api.entities.detached.IDetachableEntity; import net.dv8tion.jda.api.entities.emoji.CustomEmoji; import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; import net.dv8tion.jda.api.entities.sticker.*; @@ -92,7 +93,7 @@ * @see JDA#getGuildsByName(String, boolean) * @see JDA#getGuilds() */ -public interface Guild extends IGuildChannelContainer, ISnowflake +public interface Guild extends IGuildChannelContainer, ISnowflake, IDetachableEntity { /** Template for {@link #getIconUrl()}. */ String ICON_URL = "https://cdn.discordapp.com/icons/%s/%s.%s"; @@ -106,6 +107,9 @@ public interface Guild extends IGuildChannelContainer, ISnowflake *
This list does not include global commands! Use {@link JDA#retrieveCommands()} for global commands. *
This list does not include localization data. Use {@link #retrieveCommands(boolean)} to get localization data * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link List} of {@link Command} */ @Nonnull @@ -121,6 +125,9 @@ default RestAction> retrieveCommands() { * @param withLocalizations * {@code true} if the localization data (such as name and description) should be included * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link List} of {@link Command} */ @Nonnull @@ -136,6 +143,9 @@ default RestAction> retrieveCommands() { * @param id * The command id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @throws IllegalArgumentException * If the provided id is not a valid snowflake * @@ -154,6 +164,9 @@ default RestAction> retrieveCommands() { * @param id * The command id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link Command} */ @Nonnull @@ -178,6 +191,8 @@ default RestAction retrieveCommandById(long id) * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link Command} *
The RestAction used to create or update the command @@ -207,6 +222,8 @@ default RestAction retrieveCommandById(long id) * * @throws IllegalArgumentException * If null is provided or the name/description do not meet the requirements + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link CommandCreateAction} */ @@ -243,6 +260,9 @@ default CommandCreateAction upsertCommand(@Nonnull String name, @Nonnull String * guild.updateCommands().queue(); * } * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link CommandListUpdateAction} * * @see JDA#updateCommands() @@ -262,6 +282,8 @@ default CommandCreateAction upsertCommand(@Nonnull String name, @Nonnull String * * @throws IllegalArgumentException * If the provided id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link CommandEditAction} used to edit the command */ @@ -278,6 +300,9 @@ default CommandCreateAction upsertCommand(@Nonnull String name, @Nonnull String * @param id * The id of the command to edit * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link CommandEditAction} used to edit the command */ @Nonnull @@ -298,6 +323,8 @@ default CommandEditAction editCommandById(long id) * * @throws IllegalArgumentException * If the provided id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -314,6 +341,9 @@ default CommandEditAction editCommandById(long id) * @param commandId * The id of the command that should be deleted * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} */ @Nonnull @@ -337,6 +367,8 @@ default RestAction deleteCommandById(long commandId) * * @throws IllegalArgumentException * If the id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link List} of {@link IntegrationPrivilege} */ @@ -358,6 +390,8 @@ default RestAction deleteCommandById(long commandId) * * @throws IllegalArgumentException * If the id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link List} of {@link IntegrationPrivilege} */ @@ -374,6 +408,9 @@ default RestAction> retrieveIntegrationPrivilegesById * *

Moderators of a guild can modify these privileges through the Integrations Menu * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link PrivilegeConfig} */ @Nonnull @@ -385,6 +422,9 @@ default RestAction> retrieveIntegrationPrivilegesById *
Shortcut for {@link #retrieveRegions(boolean) retrieveRegions(true)} *
This will include deprecated voice regions by default. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction RestAction} - Type {@link java.util.EnumSet EnumSet} */ @Nonnull @@ -400,6 +440,9 @@ default RestAction> retrieveRegions() * @param includeDeprecated * Whether to include deprecated regions * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction RestAction} - Type {@link java.util.EnumSet EnumSet} */ @Nonnull @@ -411,6 +454,8 @@ default RestAction> retrieveRegions() * * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link List} of {@link AutoModRule} */ @@ -428,6 +473,8 @@ default RestAction> retrieveRegions() * If the provided id is not a valid snowflake * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link AutoModRule} */ @@ -443,6 +490,8 @@ default RestAction> retrieveRegions() * * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link AutoModRule} */ @@ -469,6 +518,8 @@ default RestAction retrieveAutoModRuleById(long id) *

  • If the provided data does not have any {@link AutoModResponse} configured
  • *
  • If any of the configured {@link AutoModResponse AutoModResponses} is not supported by the {@link AutoModTriggerType}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link AutoModRule} */ @@ -483,6 +534,8 @@ default RestAction retrieveAutoModRuleById(long id) * * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The manager instance */ @@ -497,6 +550,8 @@ default RestAction retrieveAutoModRuleById(long id) * * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The manager instance */ @@ -517,6 +572,8 @@ default AutoModRuleManager modifyAutoModRuleById(long id) * If the provided id is not a valid snowflake * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link Void} */ @@ -532,6 +589,8 @@ default AutoModRuleManager modifyAutoModRuleById(long id) * * @throws InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link Void} */ @@ -557,6 +616,8 @@ default AuditableRestAction deleteAutoModRuleById(long id) * or if the provided user reference is null or is already in this guild * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#CREATE_INSTANT_INVITE Permission.CREATE_INSTANT_INVITE} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MemberAction MemberAction} * @@ -572,6 +633,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) * Whether this guild has loaded members. *
    This will always be false if the {@link GatewayIntent#GUILD_MEMBERS GUILD_MEMBERS} intent is disabled. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True, if members are loaded. */ boolean isLoaded(); @@ -600,6 +664,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) * } * } * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @see #unloadMember(long) * @see JDA#unloadUser(long) */ @@ -616,6 +683,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) * @param userId * The target user id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True, if the cache was changed * * @see #pruneMemberCache() @@ -629,6 +699,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) * *

    When {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is disabled, this will not be updated. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The expected member count for this guild */ int getMemberCount(); @@ -638,6 +711,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) *

    * This value can be modified using {@link GuildManager#setName(String)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Never-null String containing the Guild's name. */ @Nonnull @@ -649,6 +725,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) *

    * The Guild icon can be modified using {@link GuildManager#setIcon(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null String containing the Guild's icon hash-id. */ @Nullable @@ -660,6 +739,9 @@ default AuditableRestAction deleteAutoModRuleById(long id) *

    * The Guild icon can be modified using {@link GuildManager#setIcon(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null String containing the Guild's icon URL. */ @Nullable @@ -672,6 +754,9 @@ default String getIconUrl() /** * Returns an {@link ImageProxy} for this guild's icon. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link ImageProxy} of this guild's icon * * @see #getIconUrl() @@ -715,6 +800,9 @@ default boolean isInvitesDisabled() *

    * The Guild splash can be modified using {@link GuildManager#setSplash(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null String containing the Guild's splash hash-id */ @Nullable @@ -728,6 +816,9 @@ default boolean isInvitesDisabled() *

    * The Guild splash can be modified using {@link GuildManager#setSplash(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null String containing the Guild's splash URL. */ @Nullable @@ -740,6 +831,9 @@ default String getSplashUrl() /** * Returns an {@link ImageProxy} for this guild's splash icon. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link ImageProxy} of this guild's splash icon * * @see #getSplashUrl() @@ -755,6 +849,9 @@ default ImageProxy getSplash() * The vanity url code for this Guild. The vanity url is the custom invite code of partnered / official / boosted Guilds. *
    The returned String will be the code that can be provided to {@code discord.gg/{code}} to get the invite link. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The vanity code or null * * @since 4.0.0 @@ -768,6 +865,9 @@ default ImageProxy getSplash() * The vanity url for this Guild. The vanity url is the custom invite code of partnered / official / boosted Guilds. *
    The returned String will be the vanity invite link to this guild. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The vanity url or null * * @since 4.0.0 @@ -797,6 +897,8 @@ default String getVanityUrl() * * @throws InsufficientPermissionException * If the currently logged in account does not have {@link Permission#MANAGE_SERVER Permission.MANAGE_SERVER} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link VanityInvite} * @@ -812,6 +914,9 @@ default String getVanityUrl() * *

    The description can be modified using {@link GuildManager#setDescription(String)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The description * * @since 4.0.0 @@ -838,6 +943,9 @@ default String getVanityUrl() * *

    The banner can be modified using {@link GuildManager#setBanner(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The guild banner id or null * * @since 4.0.0 @@ -853,6 +961,9 @@ default String getVanityUrl() * *

    The banner can be modified using {@link GuildManager#setBanner(Icon)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The guild banner url or null * * @since 4.0.0 @@ -867,6 +978,9 @@ default String getBannerUrl() /** * Returns an {@link ImageProxy} for this guild's banner image. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link ImageProxy} of this guild's banner image * * @see #getBannerUrl() @@ -882,6 +996,9 @@ default ImageProxy getBanner() * The boost tier for this guild. *
    Each tier unlocks new perks for a guild that can be seen in the {@link #getFeatures() features}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The boost tier. * * @since 4.0.0 @@ -892,6 +1009,9 @@ default ImageProxy getBanner() /** * The amount of boosts this server currently has. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The boost count * * @since 4.0.0 @@ -906,6 +1026,9 @@ default ImageProxy getBanner() *

    This will only check cached members! *
    See {@link net.dv8tion.jda.api.utils.MemberCachePolicy MemberCachePolicy} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of members who boost this guild */ @Nonnull @@ -916,6 +1039,9 @@ default ImageProxy getBanner() * The maximum bitrate that can be applied to a voice channel in this guild. *
    This depends on the features of this guild that can be unlocked for partners or through boosting. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The maximum bitrate * * @since 4.0.0 @@ -930,6 +1056,9 @@ default int getMaxBitrate() * Returns the maximum size for files that can be uploaded to this Guild. * This returns 8 MiB for Guilds without a Boost Tier or Guilds with Boost Tier 1, 50 MiB for Guilds with Boost Tier 2 and 100 MiB for Guilds with Boost Tier 3. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The maximum size for files that can be uploaded to this Guild * * @since 4.2.0 @@ -942,6 +1071,9 @@ default long getMaxFileSize() /** * The maximum amount of custom emojis a guild can have based on the guilds boost tier. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The maximum amount of custom emojis */ default int getMaxEmojis() @@ -953,6 +1085,9 @@ default int getMaxEmojis() /** * The maximum amount of members that can join this guild. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The maximum amount of members * * @since 4.0.0 @@ -966,6 +1101,9 @@ default int getMaxEmojis() *
    This includes members that are invisible but still connected to discord. * If too many members are online the guild will become unavailable for others. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The maximum amount of connected members this guild can have * * @since 4.0.0 @@ -977,6 +1115,9 @@ default int getMaxEmojis() /** * Loads {@link MetaData} for this guild instance. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link MetaData} * * @since 4.2.0 @@ -993,6 +1134,9 @@ default int getMaxEmojis() *

    * This value can be modified using {@link GuildManager#setAfkChannel(VoiceChannel)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link VoiceChannel VoiceChannel} that is the AFK Channel. */ @Nullable @@ -1005,6 +1149,9 @@ default int getMaxEmojis() *

    * This value can be modified using {@link GuildManager#setSystemChannel(TextChannel)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link TextChannel TextChannel} that is the system Channel. */ @Nullable @@ -1014,6 +1161,9 @@ default int getMaxEmojis() * Provides the {@link TextChannel TextChannel} that lists the rules of the guild. *
    If this guild doesn't have the COMMUNITY {@link #getFeatures() feature}, this returns {@code null}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link TextChannel TextChannel} that is the rules channel * * @see #getFeatures() @@ -1025,6 +1175,9 @@ default int getMaxEmojis() * Provides the {@link TextChannel TextChannel} that receives community updates. *
    If this guild doesn't have the COMMUNITY {@link #getFeatures() feature}, this returns {@code null}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link TextChannel TextChannel} that is the community updates channel * * @see #getFeatures() @@ -1044,6 +1197,9 @@ default int getMaxEmojis() *

    This only works when the member was added to cache. Lazy loading might load this later. *
    See {@link net.dv8tion.jda.api.utils.MemberCachePolicy MemberCachePolicy} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null Member object for the Guild owner. * * @see #getOwnerIdLong() @@ -1056,6 +1212,9 @@ default int getMaxEmojis() * The ID for the current owner of this guild. *
    This is useful for debugging purposes or as a shortcut. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The ID for the current owner * * @see #getOwner() @@ -1066,6 +1225,9 @@ default int getMaxEmojis() * The ID for the current owner of this guild. *
    This is useful for debugging purposes or as a shortcut. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The ID for the current owner * * @see #getOwner() @@ -1085,6 +1247,9 @@ default String getOwnerId() *

    * This value can be modified using {@link GuildManager#setAfkTimeout(net.dv8tion.jda.api.entities.Guild.Timeout)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link net.dv8tion.jda.api.entities.Guild.Timeout Timeout} set for this Guild. */ @Nonnull @@ -1099,6 +1264,9 @@ default String getOwnerId() * @param user * The user to check * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True - if this user is present and cached in this guild */ boolean isMember(@Nonnull UserSnowflake user); @@ -1107,6 +1275,9 @@ default String getOwnerId() * Gets the {@link net.dv8tion.jda.api.entities.Member Member} object of the currently logged in account in this guild. *
    This is basically {@link net.dv8tion.jda.api.JDA#getSelfUser()} being provided to {@link #getMember(UserSnowflake)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The Member object of the currently logged in account. */ @Nonnull @@ -1118,6 +1289,9 @@ default String getOwnerId() *

    * This value can only be modified by Discord after reviewing the Guild. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The NSFWLevel of this guild. */ @Nonnull @@ -1136,6 +1310,8 @@ default String getOwnerId() * * @throws java.lang.IllegalArgumentException * If the provided user is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link net.dv8tion.jda.api.entities.Member Member} for the related {@link net.dv8tion.jda.api.entities.User User}. * @@ -1157,6 +1333,8 @@ default String getOwnerId() * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link net.dv8tion.jda.api.entities.Member Member} with the related {@code userId}. * @@ -1180,6 +1358,9 @@ default Member getMemberById(@Nonnull String userId) * @param userId * The Discord id of the User for which a Member object is requested. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link net.dv8tion.jda.api.entities.Member Member} with the related {@code userId}. * * @see #retrieveMemberById(long) @@ -1210,6 +1391,8 @@ default Member getMemberById(long userId) * * @throws java.lang.IllegalArgumentException * If the provided tag is null or not in the described format + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link net.dv8tion.jda.api.entities.Member} for the discord tag or null if no member has the provided tag * @@ -1244,6 +1427,8 @@ default Member getMemberByTag(@Nonnull String tag) * * @throws java.lang.IllegalArgumentException * If the provided arguments are null or not in the described format + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link net.dv8tion.jda.api.entities.Member} for the discord tag or null if no member has the provided tag * @@ -1268,6 +1453,9 @@ default Member getMemberByTag(@Nonnull String username, @Nonnull String discrimi * a local variable or use {@link #getMemberCache()} and use its more efficient * versions of handling these values. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all cached members in this Guild. * * @see #loadMembers() @@ -1294,6 +1482,8 @@ default List getMembers() * * @throws IllegalArgumentException * If the provided name is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-empty immutable list of all Members with the same name as the name provided. * @@ -1322,6 +1512,9 @@ default List getMembersByName(@Nonnull String name, boolean ignoreCase) * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all Members with the same nickname as the nickname provided. * * @see #retrieveMembersByPrefix(String, int) @@ -1348,6 +1541,8 @@ default List getMembersByNickname(@Nullable String nickname, boolean ign * * @throws IllegalArgumentException * If the provided name is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-empty immutable list of all Members with the same effective name as the name provided. * @@ -1373,6 +1568,8 @@ default List getMembersByEffectiveName(@Nonnull String name, boolean ign * * @throws java.lang.IllegalArgumentException * If a provided {@link Role Role} is from a different guild or null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-empty immutable list of Members with all provided Roles. * @@ -1399,6 +1596,8 @@ default List getMembersWithRoles(@Nonnull Role... roles) * * @throws java.lang.IllegalArgumentException * If a provided {@link Role Role} is from a different guild or null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-empty immutable list of Members with all provided Roles. * @@ -1421,6 +1620,9 @@ default List getMembersWithRoles(@Nonnull Collection roles) *

    This will only provide cached members! *
    See {@link net.dv8tion.jda.api.utils.MemberCachePolicy MemberCachePolicy} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.MemberCacheView MemberCacheView} * * @see #loadMembers() @@ -1436,6 +1638,9 @@ default List getMembersWithRoles(@Nonnull Collection roles) * *

    This requires {@link CacheFlag#SCHEDULED_EVENTS} to be enabled. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link SortedSnowflakeCacheView} */ @Nonnull @@ -1456,6 +1661,8 @@ default List getMembersWithRoles(@Nonnull Collection roles) * * @throws java.lang.IllegalArgumentException * If the name is blank, empty or {@code null} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-empty immutable list of all ScheduledEvent names that match the provided name. */ @@ -1480,6 +1687,8 @@ default List getScheduledEventsByName(@Nonnull String name, bool * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link ScheduledEvent} with matching id. */ @@ -1501,6 +1710,9 @@ default ScheduledEvent getScheduledEventById(@Nonnull String id) * @param id * The id of the {@link ScheduledEvent}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link ScheduledEvent} with matching id. */ @Nullable @@ -1521,6 +1733,9 @@ default ScheduledEvent getScheduledEventById(long id) * *

    This requires {@link CacheFlag#SCHEDULED_EVENTS} to be enabled. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable List of {@link ScheduledEvent ScheduledEvents}. */ @Nonnull @@ -1569,6 +1784,9 @@ default List getScheduledEvents() *

    It is possible to filter the channels to more specific types using * {@link ChannelCacheView#getElementById(ChannelType, long)} or {@link SortedChannelCacheView#ofType(Class)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link SortedChannelCacheView SortedChannelCacheView} */ @Nonnull @@ -1593,6 +1811,9 @@ default List getScheduledEvents() * * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of channels for this guild * * @see #getChannels(boolean) @@ -1623,6 +1844,9 @@ default List getChannels() * @param includeHidden * Whether to include channels with denied {@link Permission#VIEW_CHANNEL View Channel Permission} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of channels for this guild * * @see #getChannels() @@ -1642,6 +1866,8 @@ default List getChannels() * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link Role Role} with matching id. */ @@ -1660,6 +1886,9 @@ default Role getRoleById(@Nonnull String id) * @param id * The id of the {@link Role Role}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link Role Role} with matching id. */ @Nullable @@ -1678,6 +1907,9 @@ default Role getRoleById(long id) * a local variable or use {@link #getRoleCache()} and use its more efficient * versions of handling these values. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link Role Roles}. */ @Nonnull @@ -1697,6 +1929,9 @@ default List getRoles() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all Role names that match the provided name. */ @Nonnull @@ -1719,6 +1954,9 @@ default List getRolesByName(@Nonnull String name, boolean ignoreCase) * @param userId * The user id of the bot * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The bot role, or null if no role matches */ @Nullable @@ -1746,6 +1984,8 @@ default Role getRoleByBot(long userId) * * @throws IllegalArgumentException * If the userId is null or not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The bot role, or null if no role matches */ @@ -1770,6 +2010,8 @@ default Role getRoleByBot(@Nonnull String userId) * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The bot role, or null if no role matches */ @@ -1790,6 +2032,9 @@ default Role getRoleByBot(@Nonnull User user) *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#ROLE_TAGS CacheFlag.ROLE_TAGS} to be enabled. * See {@link net.dv8tion.jda.api.JDABuilder#enableCache(CacheFlag, CacheFlag...) JDABuilder.enableCache(...)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The bot role, or null if no role matches */ @Nullable @@ -1807,6 +2052,9 @@ default Role getBotRole() *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#ROLE_TAGS CacheFlag.ROLE_TAGS} to be enabled. * See {@link net.dv8tion.jda.api.JDABuilder#enableCache(CacheFlag, CacheFlag...) JDABuilder.enableCache(...)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The boost role, or null if no role matches */ @Nullable @@ -1824,6 +2072,9 @@ default Role getBoostRole() * all cached {@link Role Roles} of this Guild. *
    Roles are sorted according to their position. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -1844,6 +2095,8 @@ default Role getBoostRole() * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return An Emoji matching the specified id * @@ -1868,6 +2121,9 @@ default RichCustomEmoji getEmojiById(@Nonnull String id) * @param id * the emoji id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An emoji matching the specified id * * @see #retrieveEmojiById(long) @@ -1891,6 +2147,9 @@ default RichCustomEmoji getEmojiById(long id) * *

    This requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#EMOJI CacheFlag.EMOJI} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link RichCustomEmoji Custom Emojis}. * * @see #retrieveEmojis() @@ -1916,6 +2175,9 @@ default List getEmojis() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all Emojis that match the provided name. */ @Nonnull @@ -1952,6 +2214,8 @@ default List getEmojisByName(@Nonnull String name, boolean igno * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A Sticker matching the specified id * @@ -1995,6 +2259,9 @@ default GuildSticker getStickerById(long id) * *

    This requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#STICKER CacheFlag.STICKER} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link net.dv8tion.jda.api.entities.sticker.GuildSticker GuildStickers}. * * @see #retrieveStickers() @@ -2018,6 +2285,9 @@ default List getStickers() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all Stickers that match the provided name. */ @Nonnull @@ -2034,6 +2304,9 @@ default List getStickersByName(@Nonnull String name, boolean ignor * *

    This requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#STICKER CacheFlag.STICKER} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SnowflakeCacheView SnowflakeCacheView} * * @see #retrieveStickers() @@ -2047,6 +2320,9 @@ default List getStickersByName(@Nonnull String name, boolean ignor *

    Note that {@link RichCustomEmoji#getOwner()} is only available if the currently * logged in account has {@link net.dv8tion.jda.api.Permission#MANAGE_GUILD_EXPRESSIONS Permission.MANAGE_GUILD_EXPRESSIONS}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction RestAction} - Type: List of {@link RichCustomEmoji} */ @Nonnull @@ -2072,6 +2348,8 @@ default List getStickersByName(@Nonnull String name, boolean ignor * * @throws IllegalArgumentException * If the provided id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: {@link RichCustomEmoji} */ @@ -2095,6 +2373,9 @@ default List getStickersByName(@Nonnull String name, boolean ignor * @param id * The emoji id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction RestAction} - Type: {@link RichCustomEmoji} */ @Nonnull @@ -2120,6 +2401,9 @@ default RestAction retrieveEmojiById(long id) * @param emoji * The emoji reference to retrieve * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link RichCustomEmoji} */ @Nonnull @@ -2147,6 +2431,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * Retrieves all the stickers from this guild. *
    This also includes {@link GuildSticker#isAvailable() unavailable} stickers. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: List of {@link GuildSticker} */ @Nonnull @@ -2168,6 +2455,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: {@link GuildSticker} *
    On request, gets the sticker with id matching provided id from Discord. @@ -2190,6 +2479,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * If null is provided * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS MANAGE_GUILD_EXPRESSIONS} in the guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link GuildStickerManager} */ @@ -2211,6 +2502,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#BAN_MEMBERS} permission. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link net.dv8tion.jda.api.requests.restaction.pagination.BanPaginationAction BanPaginationAction} of the guild's bans. */ @@ -2239,6 +2532,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#BAN_MEMBERS} permission. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: {@link net.dv8tion.jda.api.entities.Guild.Ban Ban} *
    An unmodifiable ban object for the user banned from this guild @@ -2266,6 +2561,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * If the account doesn't have {@link net.dv8tion.jda.api.Permission#KICK_MEMBERS KICK_MEMBER} Permission. * @throws IllegalArgumentException * If the provided days are less than {@code 1} or more than {@code 30} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: Integer *
    The amount of Members that would be affected. @@ -2282,6 +2579,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * it is not included in the list returned by {@link net.dv8tion.jda.api.entities.Member#getRoles() Member.getRoles()}. *
    The ID of this Role is the Guild's ID thus it is equivalent to using {@link #getRoleById(long) getRoleById(getIdLong())}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The @everyone {@link Role Role} */ @Nonnull @@ -2295,6 +2595,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) *

    Note: This channel is the first channel in the guild (ordered by position) that the {@link #getPublicRole()} * has the {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} in. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link StandardGuildChannel channel} representing the default channel for this guild */ @Nullable @@ -2307,6 +2610,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER Permission.MANAGE_SERVER} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The Manager of this Guild */ @@ -2316,6 +2621,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) /** * Returns whether this Guild has its boost progress bar shown. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True, if this Guild has its boost progress bar shown */ boolean isBoostProgressBarEnabled(); @@ -2349,6 +2657,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account * does not have the permission {@link net.dv8tion.jda.api.Permission#VIEW_AUDIT_LOGS VIEW_AUDIT_LOGS} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditLogPaginationAction AuditLogPaginationAction} */ @@ -2363,6 +2673,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws java.lang.IllegalStateException * Thrown if the currently logged in account is the Owner of this Guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: {@link java.lang.Void} */ @@ -2378,6 +2690,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * Thrown if the currently logged in account is not the owner of this Guild. * @throws java.lang.IllegalStateException * If the currently logged in account has MFA enabled. ({@link net.dv8tion.jda.api.entities.SelfUser#isMfaEnabled()}). + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link java.lang.Void} */ @@ -2399,6 +2713,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * Thrown if the currently logged in account is not the owner of this Guild. * @throws java.lang.IllegalArgumentException * If the provided {@code mfaCode} is {@code null} or empty when {@link SelfUser#isMfaEnabled()} is true. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link java.lang.Void} */ @@ -2415,6 +2731,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws IllegalStateException * If {@link GatewayIntent#GUILD_VOICE_STATES} is disabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The AudioManager for this Guild. * @@ -2439,6 +2757,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * guild.getAudioManager().openAudioConnection(stageChannel); // join the channel * } * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link Task} representing the request to speak. * Calling {@link Task#get()} can result in deadlocks and should be avoided at all times. * @@ -2453,6 +2774,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * *

    If there is no request to speak or the member is not currently connected to a {@link StageChannel}, this does nothing. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link Task} representing the request to speak cancellation. * Calling {@link Task#get()} can result in deadlocks and should be avoided at all times. * @@ -2479,6 +2803,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * if the account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} in this Guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.Invite Invite}{@literal >} *
    The list of expanded Invite objects @@ -2496,6 +2822,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * if the account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} in this Guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.templates.Template Template}{@literal >} *
    The list of Template objects @@ -2525,6 +2853,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * @throws IllegalArgumentException * If the provided name is {@code null} or not between 1-100 characters long, or * if the provided description is not between 0-120 characters long + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: {@link net.dv8tion.jda.api.entities.templates.Template Template} *
    The created Template object @@ -2542,6 +2872,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * if the account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_WEBHOOKS MANAGE_WEBHOOKS} in this Guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.Webhook Webhook}{@literal >} *
    A list of all Webhooks in this Guild. @@ -2565,6 +2897,9 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * and the currently logged in account doesn't have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link GuildWelcomeScreen} *
    The welcome screen for this Guild. */ @@ -2642,6 +2977,8 @@ default RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) * * @throws IllegalStateException * If the {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is not enabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} - Type: {@link List} of {@link Member} */ @@ -2669,6 +3006,8 @@ default Task> loadMembers() * If the provided filter is null * @throws IllegalStateException * If the {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is not enabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} - Type: {@link List} of {@link Member} */ @@ -2707,6 +3046,8 @@ default Task> findMembers(@Nonnull Predicate filter * If null is provided * @throws IllegalStateException * If the {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is not enabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} - Type: {@link List} of {@link Member} * @@ -2750,6 +3091,8 @@ default Task> findMembersWithRoles(@Nonnull Collection roles) * If null is provided * @throws IllegalStateException * If the {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is not enabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} - Type: {@link List} of {@link Member} * @@ -2780,6 +3123,8 @@ default Task> findMembersWithRoles(@Nonnull Role... roles) * If the callback is null * @throws IllegalStateException * If the {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} is not enabled + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} cancellable handle for this request */ @@ -2809,6 +3154,8 @@ default Task> findMembersWithRoles(@Nonnull Role... roles) * * @throws IllegalArgumentException * If provided with null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link Member} * @@ -2843,6 +3190,9 @@ default CacheRestAction retrieveMember(@Nonnull UserSnowflake user) * * @return {@link RestAction} - Type: {@link Member} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @see #pruneMemberCache() * @see #unloadMember(long) * @@ -2880,6 +3230,8 @@ default CacheRestAction retrieveOwner() * If the provided id is empty or null * @throws NumberFormatException * If the provided id is not a snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link Member} * @@ -2912,6 +3264,9 @@ default CacheRestAction retrieveMemberById(@Nonnull String id) * @param id * The user id to load the member from * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link Member} * * @see #pruneMemberCache() @@ -2943,6 +3298,8 @@ default CacheRestAction retrieveMemberById(@Nonnull String id) *

  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -2981,6 +3338,8 @@ default Task> retrieveMembers(@Nonnull CollectionIf the input contains null *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3019,6 +3378,8 @@ default Task> retrieveMembersByIds(@Nonnull Collection ids) *
  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3059,6 +3420,8 @@ default Task> retrieveMembersByIds(@Nonnull String... ids) *
  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3094,6 +3457,8 @@ default Task> retrieveMembersByIds(@Nonnull long... ids) *
  • If the input contains null
  • *
  • If the input is more than 100 users
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3133,6 +3498,8 @@ default Task> retrieveMembers(boolean includePresence, @Nonnull Col *
  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3172,6 +3539,8 @@ default Task> retrieveMembersByIds(boolean includePresence, @Nonnul *
  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3213,6 +3582,8 @@ default Task> retrieveMembersByIds(boolean includePresence, @Nonnul *
  • If the input contains null
  • *
  • If the input is more than 100 IDs
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request */ @@ -3241,6 +3612,8 @@ default Task> retrieveMembersByIds(boolean includePresence, @Nonnul *
  • If the provided prefix is null or empty.
  • *
  • If the provided limit is not in the range of [1, 100]
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link Task} handle for the request * @@ -3273,6 +3646,9 @@ default Task> retrieveMembersByIds(boolean includePresence, @Nonnul * @param id * The ID of the {@link ScheduledEvent} * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} - Type: {@link ScheduledEvent} * * @see #getScheduledEventById(long) @@ -3300,6 +3676,8 @@ default CacheRestAction retrieveScheduledEventById(long id) * If the specified ID is {@code null} or empty * @throws NumberFormatException * If the specified ID cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} - Type: {@link ScheduledEvent} * @@ -3354,6 +3732,8 @@ default CacheRestAction retrieveScheduledEventById(long id) *
  • If this account AND the Member being moved don't have * {@link net.dv8tion.jda.api.Permission#VOICE_CONNECT} for the destination AudioChannel.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} */ @@ -3395,6 +3775,8 @@ default CacheRestAction retrieveScheduledEventById(long id) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this account doesn't have {@link net.dv8tion.jda.api.Permission#VOICE_MOVE_OTHERS} * in the AudioChannel that the Member is currently in. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction RestAction} */ @@ -3443,6 +3825,8 @@ default RestAction kickVoiceMember(@Nonnull Member member) * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If attempting to set nickname for another member and the logged in account cannot manipulate the other user due to permission hierarchy position. *
    See {@link Member#canInteract(Member)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -3479,6 +3863,8 @@ default RestAction kickVoiceMember(@Nonnull Member member) *
  • If null is provided
  • *
  • If any of the provided roles is not from this guild
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} - Type: Integer *
    The amount of Members that were pruned from the Guild. @@ -3520,6 +3906,8 @@ default AuditableRestAction prune(int days, @Nonnull Role... roles) *
  • If null is provided
  • *
  • If any of the provided roles is not from this guild
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} - Type: Integer *
    Provides the amount of Members that were pruned from the Guild, if wait is true. @@ -3559,6 +3947,8 @@ default AuditableRestAction prune(int days, @Nonnull Role... roles) *
  • If the user cannot be kicked from this Guild or the provided {@code user} is null.
  • *
  • If the provided reason is longer than 512 characters
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -3602,6 +3992,8 @@ default AuditableRestAction kick(@Nonnull UserSnowflake user, @Nullable St * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#KICK_MEMBERS} permission. * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the logged in account cannot kick the other member due to permission hierarchy position. (See {@link Member#canInteract(Member)}) + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * Kicks the provided Member from the current Guild @@ -3664,6 +4056,8 @@ default AuditableRestAction kick(@Nonnull UserSnowflake user, @Nullable St *
  • If the provided deletionTimeframe is longer than 7 days.
  • *
  • If the provided user or time unit is {@code null}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} * @@ -3705,6 +4099,8 @@ default AuditableRestAction kick(@Nonnull UserSnowflake user, @Nullable St *
  • If the users collection is null or contains null
  • *
  • If the deletionTime is negative
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link BulkBanResponse} */ @@ -3746,6 +4142,8 @@ default AuditableRestAction kick(@Nonnull UserSnowflake user, @Nullable St *
  • If null is provided
  • *
  • If the deletionTimeframe is negative
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link BulkBanResponse} */ @@ -3778,6 +4176,8 @@ default AuditableRestAction ban(@Nonnull Collection ban(@Nonnull CollectionThe provided {@code unit} is null *
  • The provided {@code amount} with the {@code unit} results in a date that is more than {@value Member#MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -3864,6 +4266,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, long a *
  • The provided {@code duration} is null
  • *
  • The provided {@code duration} results in a date that is more than {@value Member#MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -3908,6 +4312,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu *
  • The provided {@code temporal} is in the past
  • *
  • The provided {@code temporal} is more than {@value Member#MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -3935,6 +4341,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS} permission. * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the logged in account cannot remove the timeout from the other Member due to permission hierarchy position. (See {@link Member#canInteract(Member)}) + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -3973,6 +4381,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu * If the provided user is null. * @throws java.lang.IllegalStateException * If the provided user is not currently connected to a voice channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4012,6 +4422,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu * If the provided user is null. * @throws java.lang.IllegalStateException * If the provided user is not currently connected to a voice channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4057,6 +4469,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the provided roles are higher in the Guild's hierarchy * and thus cannot be modified by the currently logged in account + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4102,6 +4516,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the provided roles are higher in the Guild's hierarchy * and thus cannot be modified by the currently logged in account + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4172,6 +4588,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu *
  • If the target member is {@code null}
  • *
  • If any of the specified Roles is managed or is the {@code Public Role} of the Guild
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4227,6 +4645,8 @@ default AuditableRestAction timeoutFor(@Nonnull UserSnowflake user, @Nonnu *
  • If any of the specified {@link Role Roles} is managed
  • *
  • If any of the specified {@link Role Roles} is the {@code Public Role} of this Guild
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -4290,6 +4710,8 @@ default AuditableRestAction modifyMemberRoles(@Nonnull Member member, @Non *
  • If any of the specified {@link Role Roles} is managed
  • *
  • If any of the specified {@link Role Roles} is the {@code Public Role} of this Guild
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -4323,6 +4745,8 @@ default AuditableRestAction modifyMemberRoles(@Nonnull Member member, @Non *
  • If the specified Member is {@code null} or not from the same Guild
  • *
  • If the specified Member already is the Guild owner
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -4351,6 +4775,8 @@ default AuditableRestAction modifyMemberRoles(@Nonnull Member member, @Non * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link net.dv8tion.jda.api.requests.restaction.ChannelAction ChannelAction} *
    This action allows to set fields for the new TextChannel before creating it @@ -4386,6 +4812,8 @@ default ChannelAction createTextChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link net.dv8tion.jda.api.requests.restaction.ChannelAction ChannelAction} *
    This action allows to set fields for the new TextChannel before creating it @@ -4415,6 +4843,8 @@ default ChannelAction createTextChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link net.dv8tion.jda.api.requests.restaction.ChannelAction ChannelAction} *
    This action allows to set fields for the new NewsChannel before creating it @@ -4450,6 +4880,8 @@ default ChannelAction createNewsChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link net.dv8tion.jda.api.requests.restaction.ChannelAction ChannelAction} *
    This action allows to set fields for the new NewsChannel before creating it @@ -4479,6 +4911,8 @@ default ChannelAction createNewsChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new VoiceChannel before creating it @@ -4514,6 +4948,8 @@ default ChannelAction createVoiceChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new VoiceChannel before creating it @@ -4543,6 +4979,8 @@ default ChannelAction createVoiceChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new StageChannel before creating it @@ -4578,6 +5016,8 @@ default ChannelAction createStageChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new StageChannel before creating it @@ -4607,6 +5047,8 @@ default ChannelAction createStageChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new ForumChannel before creating it @@ -4642,6 +5084,8 @@ default ChannelAction createForumChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new ForumChannel before creating it @@ -4671,6 +5115,8 @@ default ChannelAction createForumChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new MediaChannel before creating it @@ -4706,6 +5152,8 @@ default ChannelAction createMediaChannel(@Nonnull String name) * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters; * or the provided parent is not in the same guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new MediaChannel before creating it @@ -4735,6 +5183,8 @@ default ChannelAction createMediaChannel(@Nonnull String name) * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, blank, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new Category before creating it @@ -4776,6 +5226,8 @@ default ChannelAction createMediaChannel(@Nonnull String name) * If the provided channel is {@code null} * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL MANAGE_CHANNEL} Permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new GuildChannel before creating it! @@ -4812,6 +5264,8 @@ default ChannelAction createCopyOfChannel(@Nonnu * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES} Permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.RoleAction RoleAction} *
    Creates a new role with previously selected field values @@ -4846,6 +5300,8 @@ default ChannelAction createCopyOfChannel(@Nonnu * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES} Permission and every Permission the provided Role has * @throws java.lang.IllegalArgumentException * If the specified role is {@code null} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RoleAction RoleAction} *
    RoleAction with already copied values from the specified {@link Role Role} @@ -4887,6 +5343,8 @@ default RoleAction createCopyOfRole(@Nonnull Role role) * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_GUILD_EXPRESSIONS MANAGE_GUILD_EXPRESSIONS} Permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} - Type: {@link RichCustomEmoji} */ @@ -4923,6 +5381,8 @@ default RoleAction createCopyOfRole(@Nonnull Role role) *
  • If the asset file is null or of an invalid format (must be PNG, GIF, or LOTTIE)
  • *
  • If anything is {@code null}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link GuildSticker} */ @@ -4961,6 +5421,8 @@ default RoleAction createCopyOfRole(@Nonnull Role role) *
  • If the asset file is null or of an invalid format (must be PNG, GIF, or LOTTIE)
  • *
  • If anything is {@code null}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} - Type: {@link GuildSticker} */ @@ -4987,6 +5449,8 @@ default AuditableRestAction createSticker(@Nonnull String name, @N * If null is provided * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS MANAGE_GUILD_EXPRESSIONS} in the guild. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} */ @@ -5030,6 +5494,8 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
  • If the description is longer than 1000 characters
  • *
  • If the location is longer than 100 characters
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link ScheduledEventAction} */ @@ -5091,6 +5557,8 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
  • If the channel is not a Stage or Voice channel
  • *
  • If the channel is not from the same guild as the scheduled event
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link ScheduledEventAction} */ @@ -5114,6 +5582,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
    The currently logged in account was removed from the Guild * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.requests.restaction.order.ChannelOrderAction ChannelOrderAction} - Type: {@link Category Category} */ @Nonnull @@ -5136,6 +5607,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
    The currently logged in account was removed from the Guild * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link ChannelOrderAction ChannelOrderAction} - Type: {@link TextChannel TextChannel} */ @Nonnull @@ -5158,6 +5632,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
    The currently logged in account was removed from the Guild * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link ChannelOrderAction ChannelOrderAction} - Type: {@link VoiceChannel VoiceChannel} */ @Nonnull @@ -5188,6 +5665,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N * The {@link Category Category} to order * {@link TextChannel TextChannels} from. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.requests.restaction.order.CategoryOrderAction CategoryOrderAction} - Type: {@link TextChannel TextChannel} */ @Nonnull @@ -5218,6 +5698,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N * The {@link Category Category} to order * {@link VoiceChannel VoiceChannels} from. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link CategoryOrderAction CategoryOrderAction} - Type: {@link VoiceChannel VoiceChannels} */ @Nonnull @@ -5250,6 +5733,9 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
    The currently logged in account was removed from the Guild * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RoleOrderAction} */ @Nonnull @@ -5282,6 +5768,9 @@ default RoleOrderAction modifyRolePositions() *
    As a note: {@link net.dv8tion.jda.api.entities.Member#getRoles() Member.getRoles()} * and {@link net.dv8tion.jda.api.entities.Guild#getRoles() Guild.getRoles()} are both in descending order. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RoleOrderAction} */ @Nonnull @@ -5295,6 +5784,8 @@ default RoleOrderAction modifyRolePositions() * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER Permission.MANAGE_SERVER} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The GuildWelcomeScreenManager for this guild's welcome screen */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/IPermissionHolder.java b/src/main/java/net/dv8tion/jda/api/entities/IPermissionHolder.java index 0202b39f75..361adfb321 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/IPermissionHolder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/IPermissionHolder.java @@ -47,6 +47,9 @@ public interface IPermissionHolder extends ISnowflake * The Guild-Wide Permissions this PermissionHolder holds. *
    Changes to the returned set do not affect this entity directly. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a member and the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An EnumSet of Permissions granted to this PermissionHolder. */ @Nonnull @@ -63,6 +66,12 @@ public interface IPermissionHolder extends ISnowflake * * @throws java.lang.IllegalArgumentException * If the channel is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a role and the bot {@link Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if this is a member, the bot {@link Guild#isDetached() isn't in the guild}, + * and the combination of Member and GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. * * @return Set of Permissions granted to this Permission Holder in the specified channel. */ @@ -75,6 +84,9 @@ public interface IPermissionHolder extends ISnowflake * For a role this is identical to {@link #getPermissions()} and members have all their roles taken into consideration. *
    Changes to the returned set do not affect this entity directly. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a member and the bot {@link Guild#isDetached() isn't in the guild}. + * * @return EnumSet of the explicitly granted permissions */ @Nonnull @@ -92,6 +104,12 @@ public interface IPermissionHolder extends ISnowflake * * @throws java.lang.IllegalArgumentException * If the channel is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a role and the bot {@link Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if this is a member, the bot {@link Guild#isDetached() isn't in the guild}, + * and the combination of Member and GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. * * @return EnumSet of the explicitly granted permissions in the specified channel */ @@ -106,6 +124,8 @@ public interface IPermissionHolder extends ISnowflake * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a member and the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if all of the specified Permissions are granted to this PermissionHolder. */ @@ -120,12 +140,18 @@ public interface IPermissionHolder extends ISnowflake * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a member and the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if all of the specified Permissions are granted to this PermissionHolder. * * @see java.util.EnumSet EnumSet */ - boolean hasPermission(@Nonnull Collection permissions); + default boolean hasPermission(@Nonnull Collection permissions) + { + Checks.notNull(permissions, "Permission Collection"); + return hasPermission(permissions.toArray(Permission.EMPTY_PERMISSIONS)); + } /** * Checks whether or not this PermissionHolder has the given {@link net.dv8tion.jda.api.Permission Permissions} in the specified GuildChannel. @@ -137,6 +163,12 @@ public interface IPermissionHolder extends ISnowflake * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a role and the bot {@link Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if this is a member, the bot {@link Guild#isDetached() isn't in the guild}, + * and the combination of Member and GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. * * @return True, if all of the specified Permissions are granted to this PermissionHolder in the provided GuildChannel. * @@ -155,10 +187,20 @@ public interface IPermissionHolder extends ISnowflake * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a role and the bot {@link Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if this is a member, the bot {@link Guild#isDetached() isn't in the guild}, + * and the combination of Member and GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. * * @return True, if all of the specified Permissions are granted to this PermissionHolder in the provided GuildChannel. */ - boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Collection permissions); + default boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Collection permissions) + { + Checks.notNull(permissions, "Permission Collection"); + return hasPermission(channel, permissions.toArray(Permission.EMPTY_PERMISSIONS)); + } /** * Checks whether or not this PermissionHolder has {@link Permission#VIEW_CHANNEL VIEW_CHANNEL} @@ -169,6 +211,12 @@ public interface IPermissionHolder extends ISnowflake * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this is a role and the bot {@link Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if this is a member, the bot {@link Guild#isDetached() isn't in the guild}, + * and the combination of Member and GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. * * @return True, if the PermissionHolder has access */ @@ -194,6 +242,8 @@ default boolean hasAccess(@Nonnull GuildChannel channel) * * @throws IllegalArgumentException * If either of the channels is null or not from the same guild as this permission holder + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if the channels can be synced */ @@ -210,6 +260,8 @@ default boolean hasAccess(@Nonnull GuildChannel channel) * * @throws IllegalArgumentException * If the channel is null or not from the same guild as this permission holder + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if the channel can be synced */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/Member.java b/src/main/java/net/dv8tion/jda/api/entities/Member.java index 4106f616a2..a7451ffc15 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Member.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Member.java @@ -21,6 +21,7 @@ import net.dv8tion.jda.api.OnlineStatus; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; +import net.dv8tion.jda.api.entities.detached.IDetachableEntity; import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.requests.Route; @@ -62,7 +63,7 @@ * @see Guild#getMembersWithRoles(Role...) * @see Guild#getMembers() */ -public interface Member extends IMentionable, IPermissionHolder, UserSnowflake +public interface Member extends IMentionable, IPermissionHolder, IDetachableEntity, UserSnowflake { /** Template for {@link #getAvatarUrl()}. */ String AVATAR_URL = "https://cdn.discordapp.com/guilds/%s/users/%s/avatars/%s.%s"; @@ -167,6 +168,9 @@ default boolean isTimedOut() * *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#VOICE_STATE CacheFlag.VOICE_STATE} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.entities.GuildVoiceState GuildVoiceState} */ @Nullable @@ -178,6 +182,9 @@ default boolean isTimedOut() * *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#ACTIVITY CacheFlag.ACTIVITY} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of {@link Activity Activities} for the user */ @Nonnull @@ -190,6 +197,9 @@ default boolean isTimedOut() * *

    This will always return {@link OnlineStatus#OFFLINE} if {@link net.dv8tion.jda.api.utils.cache.CacheFlag#ONLINE_STATUS CacheFlag.ONLINE_STATUS} is disabled. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The current {@link net.dv8tion.jda.api.OnlineStatus OnlineStatus} of the {@link net.dv8tion.jda.api.entities.User User}. */ @Nonnull @@ -210,6 +220,8 @@ default boolean isTimedOut() * * @throws java.lang.IllegalArgumentException * If the provided type is null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The status for that specific client or OFFLINE * @@ -230,6 +242,9 @@ default boolean isTimedOut() *
    Since a user can be connected from multiple different devices such as web and mobile, * discord specifies a status for each {@link net.dv8tion.jda.api.entities.ClientType}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return EnumSet of all active {@link net.dv8tion.jda.api.entities.ClientType ClientTypes} * * @since 4.0.0 @@ -331,6 +346,9 @@ default ImageProxy getEffectiveAvatar() *

    The Public Role ({@code @everyone}) is not included in the returned immutable list of roles *
    It is implicit that every member holds the Public Role in a Guild thus it is not listed here!
    * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link net.dv8tion.jda.api.entities.Role Roles} for this Member. * * @see Guild#addRoleToMember(UserSnowflake, Role) @@ -393,6 +411,8 @@ default EnumSet getFlags() * if the specified Member is null * @throws IllegalArgumentException * if the specified Member is not from the same guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if this Member is able to interact with the specified Member */ @@ -411,6 +431,8 @@ default EnumSet getFlags() * if the specified Role is null * @throws IllegalArgumentException * if the specified Role is not from the same guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if this member is able to interact with the specified Role */ @@ -427,6 +449,8 @@ default EnumSet getFlags() * if the specified emoji is null * @throws IllegalArgumentException * if the specified emoji is not from the same guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if this Member is able to interact with the specified emoji */ @@ -435,6 +459,9 @@ default EnumSet getFlags() /** * Checks whether this member is the owner of its related {@link net.dv8tion.jda.api.entities.Guild Guild}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True, if this member is the owner of the attached Guild. */ boolean isOwner(); @@ -445,6 +472,9 @@ default EnumSet getFlags() * * @incubating Discord is still trying to figure this out * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return True, if this member hasn't passed the guild's Membership Screening requirements * * @since 4.2.1 @@ -460,6 +490,9 @@ default EnumSet getFlags() * {@link Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} permissions. If this requirement doesn't apply for * any channel in the guild, this method returns {@code null}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link DefaultGuildChannelUnion channel} representing the default channel for this member * or null if no such channel exists. */ @@ -503,6 +536,8 @@ default EnumSet getFlags() *

  • If the provided deletionTimeframe is longer than 7 days.
  • *
  • If the provided time unit is {@code null}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} * @@ -537,6 +572,8 @@ default AuditableRestAction ban(int deletionTimeframe, @Nonnull TimeUnit u * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the logged in account cannot kick the other member due to permission hierarchy position. *
    See {@link Member#canInteract(Member)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * Kicks the provided Member from the current Guild @@ -579,6 +616,8 @@ default AuditableRestAction kick() *
  • The provided {@code unit} is null
  • *
  • The provided {@code amount} with the {@code unit} results in a date that is more than {@value MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -616,6 +655,8 @@ default AuditableRestAction timeoutFor(long amount, @Nonnull TimeUnit unit *
  • The provided {@code duration} is not positive
  • *
  • The provided {@code duration} results in a date that is more than {@value MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -653,6 +694,8 @@ default AuditableRestAction timeoutFor(@Nonnull Duration duration) *
  • The provided {@code temporal} is in the past
  • *
  • The provided {@code temporal} is more than {@value MAX_TIME_OUT_LENGTH} days in the future
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -678,6 +721,8 @@ default AuditableRestAction timeoutUntil(@Nonnull TemporalAccessor tempora * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the logged in account does not have the {@link Permission#MODERATE_MEMBERS} permission. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -715,6 +760,8 @@ default AuditableRestAction removeTimeout() * If the logged in account does not have the {@link Permission#VOICE_DEAF_OTHERS} permission. * @throws java.lang.IllegalStateException * If the member is not currently connected to a voice channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -753,6 +800,8 @@ default AuditableRestAction mute(boolean mute) * If the logged in account does not have the {@link Permission#VOICE_DEAF_OTHERS} permission. * @throws java.lang.IllegalStateException * If the member is not currently connected to a voice channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -797,6 +846,8 @@ default AuditableRestAction deafen(boolean deafen) * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If attempting to set nickname for another member and the logged in account cannot manipulate the other user due to permission hierarchy position. *
    See {@link #canInteract(Member)}. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -822,6 +873,8 @@ default AuditableRestAction modifyNickname(@Nullable String nickname) * If the bot does not have {@link Permission#MODERATE_MEMBERS} in the guild * @throws IllegalArgumentException * If {@code null} is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/Mentions.java b/src/main/java/net/dv8tion/jda/api/entities/Mentions.java index 7e97a9b263..c3194bfc87 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Mentions.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Mentions.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.api.entities; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.channel.concrete.GroupChannel; import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.emoji.CustomEmoji; @@ -296,7 +297,7 @@ public interface Mentions *
    If none were mentioned, this list is empty. Elements are sorted in order of appearance. This only * counts direct mentions of the role and not mentions through everyone mentions. * - *

    This is always empty in {@link PrivateChannel PrivateChannels}. + *

    This is always empty in {@link PrivateChannel PrivateChannels} and {@link GroupChannel GroupChannels}. * * @return Immutable list of mentioned Members, or an empty list */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/Message.java b/src/main/java/net/dv8tion/jda/api/entities/Message.java index 9273cf69fd..c7fe90edb0 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Message.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Message.java @@ -36,6 +36,7 @@ import net.dv8tion.jda.api.entities.sticker.StickerSnowflake; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.exceptions.MissingAccessException; +import net.dv8tion.jda.api.interactions.IntegrationOwners; import net.dv8tion.jda.api.interactions.InteractionType; import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.LayoutComponent; @@ -338,7 +339,7 @@ default Message getReferencedMessage() /** * Returns the author of this Message as a {@link net.dv8tion.jda.api.entities.Member member}. *
    This is only valid if the Message was actually sent in a GuildMessageChannel. This will return {@code null} - * if the message was not sent in a GuildMessageChannel, or if the message was sent by a Webhook. + * if the message was not sent in a GuildMessageChannel, or if the message was sent by a Webhook (including apps). *
    You can check the type of channel this message was sent from using {@link #isFromType(ChannelType)} or {@link #getChannelType()}. * *

    Discord does not provide a member object for messages returned by {@link RestAction RestActions} of any kind. @@ -486,8 +487,8 @@ default Message getReferencedMessage() ChannelType getChannelType(); /** - * Indicates if this Message was sent by a {@link net.dv8tion.jda.api.entities.Webhook Webhook} instead of a - * {@link User User}. + * Indicates if this Message was sent either by a {@link net.dv8tion.jda.api.entities.Webhook Webhook} or an app, + * instead of a {@link User User}. *
    Useful if you want to ignore non-users. * * @return True if this message was sent by a {@link net.dv8tion.jda.api.entities.Webhook Webhook}. @@ -2280,10 +2281,22 @@ default MessageCreateAction replyFiles(@Nonnull Collection *

    This means responses to Message Components do not include this property, instead including a message reference object as components always exist on preexisting messages. * * @return The {@link net.dv8tion.jda.api.entities.Message.Interaction Interaction} of this message. + * + * @deprecated Replaced with {@link #getInteractionMetadata()} */ @Nullable + @Deprecated Interaction getInteraction(); + /** + * Returns the interaction metadata, + * available when the message is a response or a followup to an {@link net.dv8tion.jda.api.interactions.Interaction Interaction}. + * + * @return The {@link InteractionMetadata} of this message, or {@code null} + */ + @Nullable + InteractionMetadata getInteractionMetadata(); + /** * Creates a new, public {@link ThreadChannel} spawning/starting at this {@link Message} inside the {@link IThreadContainer} this message was sent in. *
    The starting message will copy this message, and will be of type {@link MessageType#THREAD_STARTER_MESSAGE MessageType.THREAD_STARTER_MESSAGE}. @@ -2773,7 +2786,10 @@ public DataObject toAttachmentData(int index) /** * Represents an {@link net.dv8tion.jda.api.interactions.Interaction Interaction} provided with a {@link net.dv8tion.jda.api.entities.Message Message}. + * + * @deprecated Replaced with {@link InteractionMetadata} */ + @Deprecated class Interaction implements ISnowflake { private final long id; @@ -2853,4 +2869,115 @@ public Member getMember() return member; } } + + /** + * Metadata about the interaction, including the source of the interaction and relevant server and user IDs. + * + * @see Message#getInteractionMetadata() + */ + class InteractionMetadata implements ISnowflake + { + private final long id; + private final int type; + private final User user; + private final IntegrationOwners integrationOwners; + private final Long originalResponseMessageId; + private final Long interactedMessageId; + private final InteractionMetadata triggeringInteraction; + + public InteractionMetadata(long id, int type, User user, IntegrationOwners integrationOwners, Long originalResponseMessageId, Long interactedMessageId, InteractionMetadata triggeringInteraction) + { + this.id = id; + this.type = type; + this.user = user; + this.integrationOwners = integrationOwners; + this.originalResponseMessageId = originalResponseMessageId; + this.interactedMessageId = interactedMessageId; + this.triggeringInteraction = triggeringInteraction; + } + + @Override + public long getIdLong() + { + return id; + } + + /** + * The raw interaction type. + *
    It is recommended to use {@link #getType()} instead. + * + * @return The raw interaction type + */ + public int getTypeRaw() + { + return type; + } + + /** + * The {@link net.dv8tion.jda.api.interactions.InteractionType} for this interaction. + * + * @return The {@link net.dv8tion.jda.api.interactions.InteractionType} or {@link net.dv8tion.jda.api.interactions.InteractionType#UNKNOWN} + */ + @Nonnull + public InteractionType getType() + { + return InteractionType.fromKey(type); + } + + /** + * The {@link User} who caused this interaction. + * + * @return The {@link User} + */ + @Nonnull + public User getUser() + { + return user; + } + + /** + * Returns the integration owners of this interaction, which depends on how the app was installed. + * + * @return The integration owners of this interaction + */ + @Nonnull + public IntegrationOwners getIntegrationOwners() + { + return integrationOwners; + } + + /** + * The ID of the original response message, present only on followup messages. + * + * @return The ID of the original response message, or {@code null} + */ + @Nullable + public Long getOriginalResponseMessageId() + { + return originalResponseMessageId; + } + + /** + * The ID of the message containing the component which created this message. + * + * @return the ID of the message containing the component which created this message, or {@code null} + */ + @Nullable + public Long getInteractedMessageId() + { + return interactedMessageId; + } + + /** + * Metadata for the interaction that was used to open the modal, + * present only on modal submit interactions. + * + * @return Metadata for the interaction that was used to open the modal, or {@code null} + */ + @Nullable + public InteractionMetadata getTriggeringInteraction() + { + return triggeringInteraction; + } + } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/Role.java b/src/main/java/net/dv8tion/jda/api/entities/Role.java index 10698fdb75..1f78739d83 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Role.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Role.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.entities; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.detached.IDetachableEntity; import net.dv8tion.jda.api.managers.RoleManager; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; import net.dv8tion.jda.api.requests.restaction.RoleAction; @@ -39,7 +40,7 @@ * @see JDA#getRolesByName(String, boolean) * @see JDA#getRoles() */ -public interface Role extends IMentionable, IPermissionHolder, Comparable +public interface Role extends IMentionable, IPermissionHolder, IDetachableEntity, Comparable { /** Used to keep consistency between color values used in the API */ int DEFAULT_COLOR_RAW = 0x1FFFFFFF; // java.awt.Color fills the MSB with FF, we just use 1F to provide better consistency @@ -51,6 +52,8 @@ public interface Role extends IMentionable, IPermissionHolder, Comparable * * @throws IllegalStateException * If this role is not in the guild cache + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}, use {@link #getPermissionsRaw()} instead. * * @return The position of this {@link net.dv8tion.jda.api.entities.Role Role} as integer. */ @@ -184,6 +187,8 @@ public interface Role extends IMentionable, IPermissionHolder, Comparable * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES} Permission and every Permission the provided Role has * @throws java.lang.IllegalArgumentException * If the specified guild is {@code null} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild} the role should be copied to. * * @return {@link RoleAction RoleAction} *
    RoleAction with already copied values from the specified {@link net.dv8tion.jda.api.entities.Role Role} @@ -214,6 +219,8 @@ public interface Role extends IMentionable, IPermissionHolder, Comparable * * @throws net.dv8tion.jda.api.exceptions.PermissionException * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES} Permission and every Permission the provided Role has + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RoleAction RoleAction} *
    RoleAction with already copied values from the specified {@link net.dv8tion.jda.api.entities.Role Role} @@ -234,6 +241,8 @@ default RoleAction createCopy() * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES Permission.MANAGE_ROLES} * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the currently logged in account does not have the required position to modify this role + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The RoleManager of this Role */ @@ -260,6 +269,8 @@ default RoleAction createCopy() * If we don't have the permission to {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES MANAGE_ROLES} * @throws net.dv8tion.jda.api.exceptions.HierarchyException * If the role is too high in the role hierarchy to be deleted + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java b/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java index 5a81a73cd9..ab76f865ac 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java +++ b/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java @@ -80,6 +80,9 @@ public interface WebhookClient extends ISnowflake *

  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -109,6 +112,10 @@ public interface WebhookClient extends ISnowflake *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups + * in an interaction using only {@link net.dv8tion.jda.api.interactions.IntegrationType#USER_INSTALL IntegrationType.USER_INSTALL}.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -140,6 +147,9 @@ public interface WebhookClient extends ISnowflake *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -177,6 +187,9 @@ public interface WebhookClient extends ISnowflake *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -212,6 +225,9 @@ default WebhookMessageCreateAction sendMessageFormat(@Nonnull String format, *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -259,6 +275,9 @@ default WebhookMessageCreateAction sendMessageFormat(@Nonnull String format, *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -316,6 +335,9 @@ default WebhookMessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed em *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -345,6 +367,9 @@ default WebhookMessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed em *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -407,6 +432,9 @@ default WebhookMessageCreateAction sendMessageComponents(@Nonnull LayoutCompo *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * @@ -464,6 +492,9 @@ default WebhookMessageCreateAction sendMessageComponents(@Nonnull LayoutCompo *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
    The webhook is no longer available, either it was deleted or in case of interactions it expired.
  • * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_FOLLOW_UP_MESSAGES_HIT MAX_FOLLOW_UP_MESSAGES_HIT} + *
    If this is an {@link InteractionHook InteractionHook} and you sent more than 5 follow ups in a guild the bot isn't in.
  • + * *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/Channel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/Channel.java index 9a28d43dad..013bc9bcc7 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/Channel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/Channel.java @@ -18,6 +18,7 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.IMentionable; +import net.dv8tion.jda.api.entities.detached.IDetachableEntity; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.utils.MiscUtil; @@ -30,7 +31,7 @@ /** * Abstract Channel interface for all {@link ChannelType ChannelTypes}. */ -public interface Channel extends IMentionable +public interface Channel extends IMentionable, IDetachableEntity { /** * The maximum length a channel name can be. ({@value #MAX_NAME_LENGTH}) @@ -52,6 +53,9 @@ default EnumSet getFlags() /** * The human readable name of this channel. * + *

    May be an empty string for {@link net.dv8tion.jda.api.entities.channel.concrete.GroupChannel GroupChannels} + * with no name (Group DMs with no name displays the recipients on the Discord client). + * * @return The name of this channel */ @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/ChannelType.java b/src/main/java/net/dv8tion/jda/api/entities/channel/ChannelType.java index 5177dab0ad..5ced1cb328 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/ChannelType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/ChannelType.java @@ -38,7 +38,7 @@ public enum ChannelType */ VOICE(VoiceChannel.class, 2, 1, true), /** - * A Group. (unused) + * A {@link GroupChannel GroupChannel}, used only in user apps. */ GROUP(GroupChannel.class, 3, -1), /** diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICategorizableChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICategorizableChannel.java index d890949a78..1f57a8c3f7 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICategorizableChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICategorizableChannel.java @@ -41,6 +41,9 @@ public interface ICategorizableChannel extends GuildChannel, IPermissionContaine * Computes the relative position of this channel in the {@link #getParentCategory() parent category}. *
    This is effectively the same as {@code getParentCategory().getChannels().indexOf(channel)}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return The relative position in the parent category, or {@code -1} if no parent is set */ default int getPositionInCategory() @@ -80,6 +83,9 @@ default String getParentCategoryId() *
    Note that a {@link Category Category} will * always return {@code null} for this method as nested categories are not supported. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link Category Category} for this GuildChannel */ @Nullable @@ -95,6 +101,9 @@ default Category getParentCategory() *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#MEMBER_OVERRIDES CacheFlag.MEMBER_OVERRIDES} to be enabled. *
    {@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables this CacheFlag by default. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return True, if this channel is synced with its parent category * * @since 4.2.1 diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICopyableChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICopyableChannel.java index a39f413bb4..c7c4a10d9d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICopyableChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ICopyableChannel.java @@ -63,6 +63,8 @@ public interface ICopyableChannel extends GuildChannel * If the provided guild is {@code null} * @throws net.dv8tion.jda.api.exceptions.PermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL MANAGE_CHANNEL} Permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild} the channel should be copied to. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new GuildChannel before creating it! @@ -95,6 +97,8 @@ public interface ICopyableChannel extends GuildChannel * * @throws net.dv8tion.jda.api.exceptions.PermissionException * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL MANAGE_CHANNEL} Permission + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new GuildChannel before creating it! diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IGuildChannelContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IGuildChannelContainer.java index bfb9e6d150..04f30d6287 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IGuildChannelContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IGuildChannelContainer.java @@ -56,6 +56,9 @@ public interface IGuildChannelContainer * You can use {@link ChannelCacheView#getElementById(ChannelType, long)} or {@link ChannelCacheView#ofType(Class)} to filter * out more specific types. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link ChannelCacheView} */ @Nonnull @@ -77,6 +80,8 @@ public interface IGuildChannelContainer * * @throws IllegalArgumentException * If null is provided, or the id is not a valid snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The casted channel, if it exists and is assignable to the provided class, or null */ @@ -102,6 +107,8 @@ default T getChannelById(@Nonnull Class type, @Nonnull String i * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The casted channel, if it exists and is assignable to the provided class, or null */ @@ -139,6 +146,8 @@ default T getChannelById(@Nonnull Class type, long id) * If the provided ID is null * @throws java.lang.NumberFormatException * If the provided ID is not a snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The GuildChannel or null */ @@ -172,6 +181,9 @@ default GuildChannel getGuildChannelById(@Nonnull String id) * @param id * The ID of the channel * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The GuildChannel or null */ @Nullable @@ -214,6 +226,8 @@ default GuildChannel getGuildChannelById(long id) * If the provided ID is null * @throws java.lang.NumberFormatException * If the provided ID is not a snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The GuildChannel or null */ @@ -252,6 +266,9 @@ default GuildChannel getGuildChannelById(@Nonnull ChannelType type, @Nonnull Str * @param id * The ID of the channel * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The GuildChannel or null */ @Nullable @@ -276,6 +293,9 @@ default GuildChannel getGuildChannelById(@Nonnull ChannelType type, long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -298,6 +318,9 @@ default GuildChannel getGuildChannelById(@Nonnull ChannelType type, long id) * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all StageChannel names that match the provided name. */ @Nonnull @@ -323,6 +346,8 @@ default List getStageChannelsByName(@Nonnull String name, boolean * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link StageChannel StageChannel} with matching id. */ @@ -346,6 +371,9 @@ default StageChannel getStageChannelById(@Nonnull String id) * @param id * The id of the {@link StageChannel StageChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link StageChannel StageChannel} with matching id. */ @Nullable @@ -370,6 +398,9 @@ default StageChannel getStageChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link StageChannel StageChannels}. */ @Nonnull @@ -395,6 +426,9 @@ default List getStageChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SnowflakeCacheView SnowflakeCacheView} */ @Nonnull @@ -419,6 +453,9 @@ default List getStageChannels() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all ThreadChannel names that match the provided name. */ @Nonnull @@ -446,6 +483,8 @@ default List getThreadChannelsByName(@Nonnull String name, boolea * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link ThreadChannel ThreadChannel} with matching id. */ @@ -471,6 +510,9 @@ default ThreadChannel getThreadChannelById(@Nonnull String id) * @param id * The id of the {@link ThreadChannel ThreadChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link ThreadChannel ThreadChannel} with matching id. */ @Nullable @@ -496,6 +538,9 @@ default ThreadChannel getThreadChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link ThreadChannel ThreadChannels}. */ @Nonnull @@ -520,6 +565,9 @@ default List getThreadChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -544,6 +592,8 @@ default List getThreadChannels() * * @throws java.lang.IllegalArgumentException * If the provided name is {@code null} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Immutable list of all categories matching the provided name */ @@ -570,6 +620,8 @@ default List getCategoriesByName(@Nonnull String name, boolean ignoreC * * @throws java.lang.IllegalArgumentException * If the provided ID is not a valid {@code long} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link Category Category} for the provided ID. */ @@ -593,6 +645,9 @@ default Category getCategoryById(@Nonnull String id) * @param id * The snowflake ID of the wanted Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link Category Category} for the provided ID. */ @Nullable @@ -617,6 +672,9 @@ default Category getCategoryById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable list of all {@link Category Categories} in this Guild. */ @Nonnull @@ -641,6 +699,9 @@ default List getCategories() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -663,6 +724,9 @@ default List getCategories() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all TextChannels names that match the provided name. */ @Nonnull @@ -688,6 +752,8 @@ default List getTextChannelsByName(@Nonnull String name, boolean ig * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link TextChannel TextChannel} with matching id. */ @@ -711,6 +777,9 @@ default TextChannel getTextChannelById(@Nonnull String id) * @param id * The id of the {@link TextChannel TextChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link TextChannel TextChannel} with matching id. */ @Nullable @@ -735,6 +804,9 @@ default TextChannel getTextChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of all {@link TextChannel TextChannels} in this Guild. */ @Nonnull @@ -759,6 +831,9 @@ default List getTextChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -781,6 +856,9 @@ default List getTextChannels() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all NewsChannels names that match the provided name. */ @Nonnull @@ -806,6 +884,8 @@ default List getNewsChannelsByName(@Nonnull String name, boolean ig * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link NewsChannel NewsChannel} with matching id. */ @@ -829,6 +909,9 @@ default NewsChannel getNewsChannelById(@Nonnull String id) * @param id * The id of the {@link NewsChannel NewsChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link NewsChannel NewsChannel} with matching id. */ @Nullable @@ -853,6 +936,9 @@ default NewsChannel getNewsChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of all {@link NewsChannel NewsChannels} in this Guild. */ @Nonnull @@ -877,6 +963,9 @@ default List getNewsChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView SortedSnowflakeCacheView} */ @Nonnull @@ -899,6 +988,9 @@ default List getNewsChannels() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all VoiceChannel names that match the provided name. */ @Nonnull @@ -924,6 +1016,8 @@ default List getVoiceChannelsByName(@Nonnull String name, boolean * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link VoiceChannel VoiceChannel} with matching id. */ @@ -947,6 +1041,9 @@ default VoiceChannel getVoiceChannelById(@Nonnull String id) * @param id * The id of the {@link VoiceChannel VoiceChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link VoiceChannel VoiceChannel} with matching id. */ @Nullable @@ -971,6 +1068,9 @@ default VoiceChannel getVoiceChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link VoiceChannel VoiceChannels}. */ @Nonnull @@ -994,6 +1094,9 @@ default List getVoiceChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link SnowflakeCacheView SnowflakeCacheView} */ @Nonnull @@ -1016,6 +1119,9 @@ default List getVoiceChannels() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all ForumChannel names that match the provided name. */ @Nonnull @@ -1041,6 +1147,8 @@ default List getForumChannelsByName(@Nonnull String name, boolean * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link ForumChannel} with matching id. */ @@ -1064,6 +1172,9 @@ default ForumChannel getForumChannelById(@Nonnull String id) * @param id * The id of the {@link ForumChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link ForumChannel} with matching id. */ @Nullable @@ -1087,6 +1198,9 @@ default ForumChannel getForumChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link ForumChannel}. */ @Nonnull @@ -1110,6 +1224,9 @@ default List getForumChannels() *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link SnowflakeCacheView SnowflakeCacheView} */ @Nonnull @@ -1132,6 +1249,9 @@ default List getForumChannels() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all ForumChannel names that match the provided name. */ @Nonnull @@ -1157,6 +1277,8 @@ default List getMediaChannelsByName(@Nonnull String name, boolean * * @throws java.lang.NumberFormatException * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link MediaChannel} with matching id. */ @@ -1180,6 +1302,9 @@ default MediaChannel getMediaChannelById(@Nonnull String id) * @param id * The id of the {@link MediaChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Possibly-null {@link MediaChannel} with matching id. */ @Nullable @@ -1203,6 +1328,9 @@ default MediaChannel getMediaChannelById(long id) *
    If this is called on {@link JDA} or {@link ShardManager}, this may return null immediately after building, because the cache isn't initialized yet. * To make sure the cache is initialized after building your {@link JDA} instance, you can use {@link JDA#awaitReady()}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link MediaChannel}. */ @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IInviteContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IInviteContainer.java index 16594def62..72740c97e1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IInviteContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IInviteContainer.java @@ -42,6 +42,8 @@ public interface IInviteContainer extends GuildChannel * If the account does not have {@link net.dv8tion.jda.api.Permission#CREATE_INSTANT_INVITE CREATE_INSTANT_INVITE} in this channel * @throws java.lang.IllegalArgumentException * If this is an instance of a {@link Category Category} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A new {@link InviteAction InviteAction} * @@ -58,6 +60,8 @@ public interface IInviteContainer extends GuildChannel * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * if the account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL MANAGE_CHANNEL} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.Invite Invite}{@literal >} *
    The list of expanded Invite objects diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IMemberContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IMemberContainer.java index b17c4631c3..01ff7ba1bc 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IMemberContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IMemberContainer.java @@ -51,6 +51,9 @@ public interface IMemberContainer extends GuildChannel *
    For {@link Category Categories}, * this returns all Members who are in its child channels. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return An immutable List of {@link net.dv8tion.jda.api.entities.Member Members} that are in this GuildChannel. */ @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPermissionContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPermissionContainer.java index ee30c8a01a..2af5b460ad 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPermissionContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPermissionContainer.java @@ -53,6 +53,8 @@ public interface IPermissionContainer extends GuildChannel * * @throws IllegalArgumentException * If the provided permission holder is null, or from a different guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return Possibly-null {@link net.dv8tion.jda.api.entities.PermissionOverride PermissionOverride} * relating to the provided Member or Role. @@ -70,6 +72,9 @@ public interface IPermissionContainer extends GuildChannel *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#MEMBER_OVERRIDES CacheFlag.MEMBER_OVERRIDES} to be enabled! * Without that CacheFlag, this list will only contain overrides for the currently logged in account and roles. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all {@link net.dv8tion.jda.api.entities.PermissionOverride PermissionOverrides} * for this {@link GuildChannel GuildChannel}. */ @@ -83,6 +88,9 @@ public interface IPermissionContainer extends GuildChannel * *

    This requires {@link net.dv8tion.jda.api.utils.cache.CacheFlag#MEMBER_OVERRIDES CacheFlag.MEMBER_OVERRIDES} to be enabled! * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all {@link net.dv8tion.jda.api.entities.PermissionOverride PermissionOverrides} * for {@link net.dv8tion.jda.api.entities.Member Member} * for this {@link GuildChannel GuildChannel}. @@ -100,6 +108,9 @@ default List getMemberPermissionOverrides() * Gets all of the {@link net.dv8tion.jda.api.entities.Role Role} {@link net.dv8tion.jda.api.entities.PermissionOverride PermissionOverrides} * that are part of this {@link GuildChannel GuildChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return Possibly-empty immutable list of all {@link net.dv8tion.jda.api.entities.PermissionOverride PermissionOverrides} * for {@link net.dv8tion.jda.api.entities.Role Roles} * for this {@link GuildChannel GuildChannel}. @@ -124,6 +135,8 @@ default List getRolePermissionOverrides() * If we don't have the permission to {@link net.dv8tion.jda.api.Permission#MANAGE_PERMISSIONS MANAGE_PERMISSIONS} * @throws java.lang.IllegalArgumentException * If the provided permission holder is null or not from this guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.PermissionOverrideAction} *
    With the current settings of an existing override or a fresh override with no permissions set diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPositionableChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPositionableChannel.java index e7d5936f65..95010026ee 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPositionableChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPositionableChannel.java @@ -43,6 +43,8 @@ public interface IPositionableChannel extends GuildChannel * * @throws IllegalStateException * If this channel is not in the guild cache + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return Zero-based int of position of the GuildChannel. */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPostContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPostContainer.java index dbb56edcb8..97c392add5 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPostContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IPostContainer.java @@ -228,6 +228,8 @@ default boolean isTagRequired() *

  • If null is provided
  • *
  • If the name is empty or longer than {@value Channel#MAX_NAME_LENGTH} characters
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link ForumPostAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ISlowmodeChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ISlowmodeChannel.java index b206050fd7..cc62755fe3 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ISlowmodeChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/ISlowmodeChannel.java @@ -17,9 +17,9 @@ package net.dv8tion.jda.api.entities.channel.attribute; import net.dv8tion.jda.api.entities.channel.ChannelField; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.managers.channel.ChannelManager; import net.dv8tion.jda.api.managers.channel.attribute.ISlowmodeChannelManager; -import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import javax.annotation.Nonnull; @@ -59,6 +59,8 @@ public interface ISlowmodeChannel extends GuildChannel * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL Permission.MANAGE_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return The {@link ISlowmodeChannelManager} of this {@link ISlowmodeChannel} * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IThreadContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IThreadContainer.java index b3e731d9c3..2bd40f80a1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IThreadContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IThreadContainer.java @@ -54,6 +54,9 @@ public interface IThreadContainer extends GuildChannel, IPermissionContainer * *

    These threads can also represent posts in {@link net.dv8tion.jda.api.entities.channel.concrete.ForumChannel ForumChannels}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all ThreadChannel children. */ @Nonnull @@ -101,6 +104,8 @@ default List getThreadChannels() *

  • If the bot does not have {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • If the bot does not have {@link net.dv8tion.jda.api.Permission#CREATE_PUBLIC_THREADS Permission.CREATE_PUBLIC_THREADS}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A specific {@link ThreadChannelAction} that may be used to configure the new ThreadChannel before its creation. */ @@ -155,6 +160,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name) *
  • If the thread is {@code private}, and the bot does not have {@link net.dv8tion.jda.api.Permission#CREATE_PRIVATE_THREADS Permission.CREATE_PRIVATE_THREADS}
  • *
  • If the thread is not {@code private}, and the bot does not have {@link net.dv8tion.jda.api.Permission#CREATE_PUBLIC_THREADS Permission.CREATE_PUBLIC_THREADS}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A specific {@link ThreadChannelAction} that may be used to configure the new ThreadChannel before its creation. */ @@ -200,6 +207,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name) * You must use {@link net.dv8tion.jda.api.entities.channel.concrete.ForumChannel#createForumPost(String, MessageCreateData) createForumPost(...)} instead. * @throws InsufficientPermissionException * If the bot does not have {@link net.dv8tion.jda.api.Permission#CREATE_PUBLIC_THREADS Permission.CREATE_PUBLIC_THREADS} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A specific {@link ThreadChannelAction} that may be used to configure the new ThreadChannel before its creation. */ @@ -247,6 +256,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name) * You must use {@link net.dv8tion.jda.api.entities.channel.concrete.ForumChannel#createForumPost(String, MessageCreateData) createForumPost(...)} instead. * @throws InsufficientPermissionException * If the bot does not have {@link net.dv8tion.jda.api.Permission#CREATE_PUBLIC_THREADS Permission.CREATE_PUBLIC_THREADS} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A specific {@link ThreadChannelAction} that may be used to configure the new ThreadChannel before its creation. */ @@ -267,6 +278,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, @Nonnull S * * @throws InsufficientPermissionException * If the bot does not have {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link ThreadChannelPaginationAction} to iterate over all public archived ThreadChannels */ @@ -286,6 +299,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, @Nonnull S * @throws InsufficientPermissionException * If the bot does not have {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY} * or {@link net.dv8tion.jda.api.Permission#MANAGE_THREADS Permission.MANAGE_THREADS} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link ThreadChannelPaginationAction} to iterate over all private archived ThreadChannels */ @@ -303,6 +318,8 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, @Nonnull S * * @throws InsufficientPermissionException * If the bot does not have {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY} in this channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link ThreadChannelPaginationAction} to iterate over all joined private archived ThreadChannels */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IVoiceStatusChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IVoiceStatusChannel.java index 47195b4eb4..c98804626d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IVoiceStatusChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IVoiceStatusChannel.java @@ -59,6 +59,8 @@ public interface IVoiceStatusChannel extends Channel *
  • If the currently logged in account is not connected and does not have the {@link Permission#MANAGE_CHANNEL MANAGE_CHANNEL} permission.
  • *
  • If the currently logged in account is connected and does not have the {@link Permission#VOICE_SET_STATUS VOICE_SET_STATUS} permission.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link AuditableRestAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IWebhookContainer.java b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IWebhookContainer.java index 70fb42b5dd..5958efb9bd 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IWebhookContainer.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/attribute/IWebhookContainer.java @@ -49,6 +49,8 @@ public interface IWebhookContainer extends GuildChannel * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#MANAGE_WEBHOOKS Permission.MANAGE_WEBHOOKS} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.Webhook Webhook}{@literal >} *
    Retrieved an immutable list of Webhooks attached to this channel @@ -81,6 +83,8 @@ public interface IWebhookContainer extends GuildChannel * @throws IllegalArgumentException * If the provided name is {@code null}, blank or not * between 2-100 characters in length + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return A specific {@link WebhookAction WebhookAction} *
    This action allows to set fields for the new webhook before creating it @@ -118,6 +122,8 @@ public interface IWebhookContainer extends GuildChannel * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#MANAGE_WEBHOOKS Permission.MANAGE_WEBHOOKS} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/Category.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/Category.java index 09a94d7738..b39cafa1d2 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/Category.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/Category.java @@ -55,6 +55,9 @@ public interface Category extends GuildChannel, ICopyableChannel, IPositionableC * All {@link GuildChannel Channels} listed for this Category. *
    Includes all types of channels, except for threads. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child channels */ @Nonnull @@ -75,6 +78,9 @@ default List getChannels() * All {@link TextChannel TextChannels} * listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child TextChannels */ @Nonnull @@ -92,6 +98,9 @@ default List getTextChannels() * All {@link NewsChannel NewsChannels} * listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child NewsChannels */ @Nonnull @@ -108,6 +117,9 @@ default List getNewsChannels() /** * All {@link net.dv8tion.jda.api.entities.channel.concrete.ForumChannel ForumChannels} listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child ForumChannels */ @Nonnull @@ -124,6 +136,9 @@ default List getForumChannels() /** * All {@link net.dv8tion.jda.api.entities.channel.concrete.MediaChannel MediaChannels} listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child ForumChannels */ @Nonnull @@ -141,6 +156,9 @@ default List getMediaChannels() * All {@link VoiceChannel VoiceChannels} * listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child VoiceChannels */ @Nonnull @@ -158,6 +176,9 @@ default List getVoiceChannels() * All {@link StageChannel StageChannel} * listed for this Category * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable list of all child StageChannel */ @Nonnull @@ -200,6 +221,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new TextChannel before creating it @@ -237,6 +260,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new NewsChannel before creating it @@ -274,6 +299,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new VoiceChannel before creating it @@ -311,6 +338,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new StageChannel before creating it @@ -348,6 +377,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new ForumChannel before creating it @@ -385,6 +416,8 @@ default List getStageChannels() * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL} permission * @throws IllegalArgumentException * If the provided name is {@code null}, empty, or longer than {@value Channel#MAX_NAME_LENGTH} characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A specific {@link ChannelAction ChannelAction} *
    This action allows to set fields for the new MediaChannel before creating it @@ -413,6 +446,9 @@ default List getStageChannels() *
    The currently logged in account was removed from the Guild. * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return A {@link CategoryOrderAction CategoryOrderAction} for * ordering the Category's {@link TextChannel TextChannels} * and {@link NewsChannel NewsChannels}. @@ -441,6 +477,9 @@ default List getStageChannels() *
    The currently logged in account was removed from the Guild. * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return A {@link CategoryOrderAction CategoryOrderAction} for * ordering the Category's {@link VoiceChannel VoiceChannels} * and {@link StageChannel StageChannels}. diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/GroupChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/GroupChannel.java index acec1d8433..985adb93de 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/GroupChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/GroupChannel.java @@ -16,13 +16,80 @@ package net.dv8tion.jda.api.entities.channel.concrete; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.UserSnowflake; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.entities.detached.IDetachableEntity; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.utils.ImageProxy; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Represents a Group DM channel. * - *

    This is currently unused. + *

    This is only used for user-installed apps. */ -public interface GroupChannel extends MessageChannel +public interface GroupChannel extends MessageChannel, IDetachableEntity { + /** Template for {@link #getIconUrl()}. */ + String ICON_URL = "https://cdn.discordapp.com/channel-icons/%s/%s.png"; + + /** + * The Discord hash-id of the group channel icon image. + * If no icon has been set, this returns {@code null}. + * + * @return Possibly-null String containing the group channel's icon hash-id. + */ + @Nullable + String getIconId(); + + /** + * The URL of the group channel icon image. + * If no icon has been set, this returns {@code null}. + * + * @return Possibly-null String containing the group channel's icon URL. + */ + @Nullable + default String getIconUrl() + { + String iconId = getIconId(); + return iconId == null ? null : String.format(ICON_URL, getId(), iconId); + } + + /** + * Returns an {@link ImageProxy} for this group channel's icon. + * + * @return Possibly-null {@link ImageProxy} of this group channel's icon + * + * @see #getIconUrl() + */ + @Nullable + default ImageProxy getIcon() + { + final String iconUrl = getIconUrl(); + return iconUrl == null ? null : new ImageProxy(iconUrl); + } + + /** + * Returns the ID of the user which owns this {@link GroupChannel}. + * + * @return The ID of the user which owns this {@link GroupChannel} + */ + @Nonnull + UserSnowflake getOwnerId(); + + /** + * Retrieves the {@link User} which owns this {@link GroupChannel}. + * + * @return A {@link RestAction} to retrieve the {@link User User} which owns this {@link GroupChannel}. + */ + @Nonnull + @CheckReturnValue + default RestAction retrieveOwner() + { + return getJDA().retrieveUserById(getOwnerId().getIdLong()); + } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/NewsChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/NewsChannel.java index f5c79ebfdb..a95b2c936c 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/NewsChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/NewsChannel.java @@ -67,6 +67,8 @@ public interface NewsChannel extends StandardGuildMessageChannel * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} * @@ -95,6 +97,9 @@ public interface NewsChannel extends StandardGuildMessageChannel * @param targetChannelId * The target channel id * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link RestAction} * * @since 4.2.1 @@ -131,6 +136,8 @@ default RestAction follow(long targetChannelId) * If the currently logged in account does not have {@link Permission#MANAGE_WEBHOOKS} in the target channel. * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} * @@ -184,6 +191,8 @@ default RestAction follow(@Nonnull TextChannel targetC * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} - Type: {@link Message} * @@ -195,6 +204,7 @@ default RestAction crosspostMessageById(@Nonnull String messageId) { Checks.isSnowflake(messageId); Checks.checkAccess(getGuild().getSelfMember(), this); + Checks.checkAttached(this); Route.CompiledRoute route = Route.Messages.CROSSPOST_MESSAGE.compile(getId(), messageId); return new RestActionImpl<>(getJDA(), route, (response, request) -> request.getJDA().getEntityBuilder().createMessageWithChannel(response.getObject(), this, false)); @@ -232,6 +242,8 @@ default RestAction crosspostMessageById(@Nonnull String messageId) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} - Type: {@link Message} * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/PrivateChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/PrivateChannel.java index 6df959b41b..0863dc4967 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/PrivateChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/PrivateChannel.java @@ -15,6 +15,7 @@ */ package net.dv8tion.jda.api.entities.channel.concrete; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.requests.RestAction; @@ -39,6 +40,8 @@ public interface PrivateChannel extends MessageChannel *

  • A reaction is added
  • *
  • A message is deleted
  • *
  • This account sends a message to a user from another shard (not shard 0)
  • + *
  • This account receives an interaction response, happens when using an user-installed interaction
  • + *
  • This channel represents a DM channel between friends, happens when using an user-installed interaction
  • * * The consequence of this is that for any message this bot receives from a guild or from other users, the user will not be null. * @@ -56,6 +59,9 @@ public interface PrivateChannel extends MessageChannel * *
    This method fetches the channel from the API and retrieves the User from that. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if this channel is {@link Guild#isDetached() detached}, representing a friend DMs. + * * @return A {@link RestAction RestAction} to retrieve the {@link User User} that this {@link PrivateChannel PrivateChannel} communicates with. */ @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/StageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/StageChannel.java index d981754c91..b35f9ad54a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/StageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/StageChannel.java @@ -80,6 +80,8 @@ public interface StageChannel extends StandardGuildChannel, GuildMessageChannel, * If the self member is not a stage moderator. (See {@link #isModerator(Member)}) * @throws IllegalArgumentException * If the topic is null, empty, or longer than 120 characters + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link StageInstanceAction} */ @@ -87,6 +89,7 @@ public interface StageChannel extends StandardGuildChannel, GuildMessageChannel, @CheckReturnValue default StageInstanceAction createStageInstance(@Nonnull String topic) { + Checks.checkAttached(this); EnumSet permissions = getGuild().getSelfMember().getPermissions(this); EnumSet required = EnumSet.of(Permission.MANAGE_CHANNEL, Permission.VOICE_MUTE_OTHERS, Permission.VOICE_MOVE_OTHERS); for (Permission perm : required) @@ -146,6 +149,8 @@ default ChannelAction createCopy() * * @throws IllegalStateException * If the self member is not currently connected to the channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} * @@ -163,6 +168,8 @@ default ChannelAction createCopy() * * @throws IllegalStateException * If the self member is not currently connected to the channel + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ThreadChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ThreadChannel.java index 7ac41fda1d..ab7dc30214 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ThreadChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ThreadChannel.java @@ -104,6 +104,9 @@ default boolean isPublic() /** * Whether the currently logged in member has joined this thread. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return true if the self member has joined this thread, false otherwise. */ default boolean isJoined() @@ -153,6 +156,9 @@ default boolean isPinned() /** * Gets the {@link IThreadContainer parent channel} of this thread. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The parent channel of this thread. * * @see IThreadContainer#getThreadChannels() @@ -166,6 +172,8 @@ default boolean isPinned() * * @throws UnsupportedOperationException * If the parent channel is not a {@link GuildMessageChannel}. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The parent channel of this thread, as a {@link GuildMessageChannelUnion}. */ @@ -182,6 +190,9 @@ default GuildMessageChannelUnion getParentMessageChannel() * The {@link net.dv8tion.jda.api.entities.channel.forums.ForumTag forum tags} applied to this thread. *
    This will be an empty list if the thread was not created in a {@link net.dv8tion.jda.api.entities.channel.concrete.ForumChannel ForumChannel}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return Immutable {@link List} of {@link net.dv8tion.jda.api.entities.channel.forums.ForumTag ForumTags} applied to this post */ @Nonnull @@ -221,6 +232,8 @@ default GuildMessageChannelUnion getParentMessageChannel() * * @throws UnsupportedOperationException * If the parent channel is not a {@link GuildMessageChannel GuildMessageChannel}. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Message *
    The Message that started this thread @@ -263,6 +276,8 @@ default GuildMessageChannelUnion getParentMessageChannel() *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Message */ @@ -275,6 +290,9 @@ default GuildMessageChannelUnion getParentMessageChannel() * *

    If the current account is not a member of this thread, this will return null. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The self member of this thread, null if the current account is not a member of this thread. * * @see #isJoined() @@ -302,6 +320,9 @@ default ThreadMember getSelfThreadMember() *

  • the bot must have be online to receive the update
  • * * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return List of all {@link ThreadMember members} of this thread. This list may be empty, but not null. * * @see #retrieveThreadMembers() @@ -322,6 +343,8 @@ default ThreadMember getSelfThreadMember() * * @throws IllegalArgumentException * If the given member is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link ThreadMember} of this thread for the given member. * @@ -347,6 +370,8 @@ default ThreadMember getThreadMember(@Nonnull Member member) * * @throws IllegalArgumentException * If the given user is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link ThreadMember} of this thread for the given member. * @@ -372,6 +397,8 @@ default ThreadMember getThreadMember(@Nonnull User user) * * @throws IllegalArgumentException * If the given id is null or empty. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link ThreadMember} of this thread for the given member. * @@ -394,6 +421,9 @@ default ThreadMember getThreadMemberById(@Nonnull String id) * @param id * The member to get the {@link ThreadMember} for. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link ThreadMember} of this thread for the given member. * * @see #retrieveThreadMember(Member) @@ -412,6 +442,8 @@ default ThreadMember getThreadMemberById(@Nonnull String id) * * @throws IllegalArgumentException * If provided with null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link CacheRestAction} - Type: {@link ThreadMember} */ @@ -434,6 +466,8 @@ default CacheRestAction retrieveThreadMember(@Nonnull Member membe * * @throws IllegalArgumentException * If provided with null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link CacheRestAction} - Type: {@link ThreadMember} */ @@ -458,6 +492,8 @@ default CacheRestAction retrieveThreadMember(@Nonnull User user) * If the provided id is empty or null * @throws NumberFormatException * If the provided id is not a snowflake + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link CacheRestAction} - Type: {@link ThreadMember} */ @@ -477,6 +513,9 @@ default CacheRestAction retrieveThreadMemberById(@Nonnull String i * @param id * The user id to load the thread-member from * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link CacheRestAction} - Type: {@link ThreadMember} */ @Nonnull @@ -489,6 +528,9 @@ default CacheRestAction retrieveThreadMemberById(@Nonnull String i *

    This requires the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_MEMBERS} intent to be enabled * in the Application Dashboard. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link ThreadMemberPaginationAction} */ @Nonnull @@ -529,6 +571,9 @@ default String getOwnerId() * and so it is recommended to {@link Guild#retrieveMemberById(long) retrieve this member from the guild} * using {@link #getOwnerIdLong() the owner'd ID}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The {@link Member} of the member who created this thread. * * @see #getThreadMemberById(long) @@ -548,6 +593,9 @@ default Member getOwner() * and so it is recommended to {@link #retrieveThreadMemberById(long) retrieve the ThreadMember} * by {@link #getOwnerIdLong() their ID} instead. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The owner of this thread as a {@link ThreadMember}. * * @see #getThreadMemberById(long) @@ -637,6 +685,8 @@ default ThreadMember getOwnerThreadMember() * * @throws IllegalStateException * If this thread is archived. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -660,6 +710,8 @@ default ThreadMember getOwnerThreadMember() * * @throws IllegalStateException * If this thread is archived. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -705,6 +757,8 @@ default ThreadMember getOwnerThreadMember() * * @throws IllegalStateException * If this thread is archived. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -752,6 +806,8 @@ default ThreadMember getOwnerThreadMember() * If this thread is locked or archived * @throws IllegalArgumentException * If the provided id is not a valid snowflake. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -795,6 +851,8 @@ default RestAction addThreadMemberById(@Nonnull String id) * If this thread is locked or archived. * @throws IllegalArgumentException * If the provided user is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -839,6 +897,8 @@ default RestAction addThreadMember(@Nonnull User user) * If this thread is locked or archived. * @throws IllegalArgumentException * If the provided member is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -879,6 +939,8 @@ default RestAction addThreadMember(@Nonnull Member member) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_THREADS} permission, * and this is not a private thread channel this account owns. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -917,6 +979,8 @@ default RestAction addThreadMember(@Nonnull Member member) * and this is not a private thread channel this account owns. * @throws IllegalArgumentException * If the provided id is not a valid snowflake. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -952,6 +1016,8 @@ default RestAction removeThreadMemberById(@Nonnull String id) * and this is not a private thread channel this account owns. * @throws IllegalArgumentException * If the provided user is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -988,6 +1054,8 @@ default RestAction removeThreadMember(@Nonnull User user) * If the account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_THREADS} permission, and this isn't a private thread channel this account owns. * @throws IllegalArgumentException * If the provided member is null. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildChannel.java index c1c8325df5..65b0da5acb 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildChannel.java @@ -57,6 +57,8 @@ public interface GuildChannel extends Channel, Comparable * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL Permission.MANAGE_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The ChannelManager of this GuildChannel */ @@ -83,6 +85,9 @@ public interface GuildChannel extends Channel, Comparable * if the currently logged in account doesn't have {@link net.dv8tion.jda.api.Permission#MANAGE_CHANNEL MANAGE_CHANNEL} * for the channel. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @Override @@ -95,6 +100,9 @@ public interface GuildChannel extends Channel, Comparable * *

    This is usually the same channel, but for threads the parent channel is used instead. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return The permission container */ @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildMessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildMessageChannel.java index 6c66ab0753..6d6e33dd44 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildMessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/GuildMessageChannel.java @@ -62,6 +62,14 @@ default boolean canTalk() *
    Checks for both {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} and * {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND}. * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * If this channel is a thread, + * and the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. + * @throws net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}, + * and the combination of the provided Member and this GuildChannel doesn't have permission data, + * see {@link net.dv8tion.jda.api.exceptions.MissingEntityInteractionPermissionsException MissingEntityInteractionPermissionsException}. + * * @param member * The Member to check * @@ -116,6 +124,8 @@ default boolean canTalk() * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -170,6 +180,8 @@ default boolean canTalk() * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -217,6 +229,8 @@ default RestAction removeReactionById(long messageId, @Nonnull Emoji emoji * If the size of the list less than 2 or more than 100 messages. * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this account does not have {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -274,6 +288,8 @@ default RestAction deleteMessages(@Nonnull Collection messages) * If any of the provided ids cannot be parsed by {@link Long#parseLong(String)} * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this account does not have {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} * @@ -312,6 +328,8 @@ default RestAction deleteMessages(@Nonnull Collection messages) * {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} in this channel. * @throws java.lang.IllegalArgumentException * If the provided {@code id} is {@code null} or empty. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -345,6 +363,8 @@ default RestAction deleteMessages(@Nonnull Collection messages) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have * {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE} in this channel. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction} */ @@ -380,6 +400,8 @@ default RestAction clearReactionsById(long messageId) * If the currently logged in account does not have {@link Permission#MESSAGE_MANAGE} in the channel * @throws IllegalArgumentException * If provided with null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -412,6 +434,8 @@ default RestAction clearReactionsById(long messageId) * If the currently logged in account does not have {@link Permission#MESSAGE_MANAGE} in the channel * @throws IllegalArgumentException * If provided with null + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link RestAction} */ @@ -444,6 +468,8 @@ default RestAction clearReactionsById(long messageId, @Nonnull Emoji emoji *

  • If the list is empty or has more than 3 stickers
  • *
  • If null is provided
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} * @@ -475,6 +501,8 @@ default RestAction clearReactionsById(long messageId, @Nonnull Emoji emoji *
  • If the list is empty or has more than 3 stickers
  • *
  • If null is provided
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java index 1483676ce3..90ae1fcf56 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java @@ -20,6 +20,7 @@ import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageHistory; import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.concrete.GroupChannel; import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; @@ -137,6 +138,10 @@ default String getLatestMessageId() *
    For {@link ThreadChannel} this method checks for {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND_IN_THREADS} instead of {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND}. *
    For {@link PrivateChannel} this method checks if the user that this PrivateChannel communicates with is not a bot, * but it does not check if the said user blocked the currently logged in user or have their DMs disabled. + *
    For {@link GroupChannel} this method returns false. + * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return True, if we are able to read and send messages in this channel */ @@ -153,6 +158,9 @@ default String getLatestMessageId() * @param messageIds * The message ids to delete * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return List of futures representing all deletion tasks * * @see CompletableFuture#allOf(java.util.concurrent.CompletableFuture[]) @@ -179,6 +187,9 @@ default List> purgeMessagesById(@Nonnull List me * @param messageIds * The message ids to delete * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. + * * @return List of futures representing all deletion tasks * * @see CompletableFuture#allOf(java.util.concurrent.CompletableFuture[]) @@ -206,6 +217,8 @@ default List> purgeMessagesById(@Nonnull String... messa * If one of the provided messages is from another user and cannot be deleted due to permissions * @throws IllegalArgumentException * If one of the provided messages is from another user and cannot be deleted because this is not in a guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return List of futures representing all deletion tasks * @@ -236,6 +249,8 @@ default List> purgeMessages(@Nonnull Message... messages * If one of the provided messages is from another user and cannot be deleted due to permissions * @throws IllegalArgumentException * If one of the provided messages is from another user and cannot be deleted because this is not in a guild + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return List of futures representing all deletion tasks * @@ -277,6 +292,9 @@ default List> purgeMessages(@Nonnull List> purgeMessagesById(@Nonnull long... message * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} */ @@ -364,6 +384,8 @@ default MessageCreateAction sendMessage(@Nonnull CharSequence text) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} * @@ -415,6 +437,8 @@ default MessageCreateAction sendMessage(@Nonnull MessageCreateData msg) * illegal conditions. For specification of all possible * formatting errors, see the Details section of the * formatter class specification. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} */ @@ -475,6 +499,8 @@ default MessageCreateAction sendMessageFormat(@Nonnull String format, @Nonnull O * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} */ @@ -537,6 +563,8 @@ default MessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed embed, @Nonn * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} */ @@ -578,6 +606,8 @@ default MessageCreateAction sendMessageEmbeds(@Nonnull Collection * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageCreateAction} * @@ -871,6 +907,8 @@ default MessageCreateAction sendFiles(@Nonnull FileUpload... files) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Message *
    The Message defined by the provided id. @@ -922,6 +960,8 @@ default RestAction retrieveMessageById(@Nonnull String messageId) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Message *
    The Message defined by the provided id. @@ -967,6 +1007,8 @@ default RestAction retrieveMessageById(long messageId) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and the logged in account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Void */ @@ -1014,6 +1056,8 @@ default AuditableRestAction deleteMessageById(@Nonnull String messageId) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and the logged in account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Void */ @@ -1133,6 +1177,8 @@ default PollVotersPaginationAction retrievePollVotersById(long messageId, long a * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} * and the currently logged in account does not have the permission {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY MESSAGE_HISTORY} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return A {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} related to this channel. */ @@ -1167,6 +1213,8 @@ default MessageHistory getHistory() * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} * and the currently logged in account does not have the permission {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY MESSAGE_HISTORY} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessagePaginationAction MessagePaginationAction} */ @@ -1230,6 +1278,8 @@ default MessagePaginationAction getIterableHistory() *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages around the provided message loaded into it. @@ -1296,6 +1346,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAround(@Nonnull String me *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages around the provided message loaded into it. @@ -1362,6 +1414,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAround(long messageId, in *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages around the provided message loaded into it. @@ -1421,6 +1475,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAround(@Nonnull Message m *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages after the provided message loaded into it. @@ -1476,6 +1532,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAfter(@Nonnull String mes *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages after the provided message loaded into it. @@ -1534,6 +1592,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAfter(long messageId, int *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages after the provided message loaded into it. @@ -1593,6 +1653,8 @@ default MessageHistory.MessageRetrieveAction getHistoryAfter(@Nonnull Message me *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages before the provided message loaded into it. @@ -1651,6 +1713,8 @@ default MessageHistory.MessageRetrieveAction getHistoryBefore(@Nonnull String me *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages before the provided message loaded into it. @@ -1709,6 +1773,8 @@ default MessageHistory.MessageRetrieveAction getHistoryBefore(long messageId, in *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with messages before the provided message loaded into it. @@ -1771,6 +1837,8 @@ default MessageHistory.MessageRetrieveAction getHistoryBefore(@Nonnull Message m *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.entities.MessageHistory.MessageRetrieveAction MessageHistory.MessageRetrieveAction} *
    Provides a {@link net.dv8tion.jda.api.entities.MessageHistory MessageHistory} object with with the first messages of this channel loaded into it. @@ -1811,6 +1879,8 @@ default MessageHistory.MessageRetrieveAction getHistoryFromBeginning(int limit) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: Void */ @@ -1868,6 +1938,8 @@ default RestAction sendTyping() *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_ADD_REACTION Permission.MESSAGE_ADD_REACTION}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -1928,6 +2000,8 @@ default RestAction addReactionById(@Nonnull String messageId, @Nonnull Emo *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_ADD_REACTION Permission.MESSAGE_ADD_REACTION}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -1977,6 +2051,8 @@ default RestAction addReactionById(long messageId, @Nonnull Emoji emoji) *
  • If provided {@code messageId} is {@code null} or not a valid snowflake.
  • *
  • If provided {@code emoji} is {@code null}.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -2030,6 +2106,8 @@ default RestAction removeReactionById(@Nonnull String messageId, @Nonnull *
  • If provided {@code messageId} is not a valid snowflake.
  • *
  • If provided {@code emoji} is {@code null}.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction} */ @@ -2076,6 +2154,8 @@ default RestAction removeReactionById(long messageId, @Nonnull Emoji emoji *
  • If provided {@code messageId} is {@code null} or not a valid snowflake.
  • *
  • If provided {@code emoji} is {@code null}.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link ReactionPaginationAction} of the emoji's users. */ @@ -2127,6 +2207,8 @@ default ReactionPaginationAction retrieveReactionUsersById(@Nonnull String messa *
  • If provided {@code messageId} is not a valid snowflake.
  • *
  • If provided {@code emoji} is {@code null}.
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return The {@link ReactionPaginationAction ReactionPaginationAction} of the emoji's users. * @@ -2173,6 +2255,8 @@ default ReactionPaginationAction retrieveReactionUsersById(long messageId, @Nonn *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} */ @@ -2220,6 +2304,8 @@ default RestAction pinMessageById(@Nonnull String messageId) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} */ @@ -2264,6 +2350,8 @@ default RestAction pinMessageById(long messageId) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} */ @@ -2311,6 +2399,8 @@ default RestAction unpinMessageById(@Nonnull String messageId) *
  • {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
  • *
  • {@link net.dv8tion.jda.api.Permission#MESSAGE_MANAGE Permission.MESSAGE_MANAGE}
  • * + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} */ @@ -2339,6 +2429,8 @@ default RestAction unpinMessageById(long messageId) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: List{@literal <}{@link net.dv8tion.jda.api.entities.Message}{@literal >} *
    Retrieves an immutable list of pinned messages @@ -2407,6 +2499,8 @@ default RestAction unpinMessageById(long messageId) * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2455,6 +2549,8 @@ default MessageEditAction editMessageById(@Nonnull String messageId, @Nonnull Ch * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2503,6 +2599,8 @@ default MessageEditAction editMessageById(long messageId, @Nonnull CharSequence * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2552,6 +2650,8 @@ default MessageEditAction editMessageById(@Nonnull String messageId, @Nonnull Me * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2608,6 +2708,8 @@ default MessageEditAction editMessageById(long messageId, @Nonnull MessageEditDa * For specification of all possible formatting errors, * see the Details * section of the formatter class specification. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2662,6 +2764,8 @@ default MessageEditAction editMessageFormatById(@Nonnull String messageId, @Nonn * For specification of all possible formatting errors, * see the Details * section of the formatter class specification. + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2710,6 +2814,8 @@ default MessageEditAction editMessageFormatById(long messageId, @Nonnull String * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2758,6 +2864,8 @@ default MessageEditAction editMessageEmbedsById(@Nonnull String messageId, @Nonn * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2805,6 +2913,8 @@ default MessageEditAction editMessageEmbedsById(long messageId, @Nonnull Message * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2853,6 +2963,8 @@ default MessageEditAction editMessageEmbedsById(@Nonnull String messageId, @Nonn * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2913,6 +3025,8 @@ default MessageEditAction editMessageEmbedsById(long messageId, @Nonnull Collect * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -2975,6 +3089,8 @@ default MessageEditAction editMessageComponentsById(@Nonnull String messageId, @ * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -3034,6 +3150,8 @@ default MessageEditAction editMessageComponentsById(long messageId, @Nonnull Col * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -3091,6 +3209,8 @@ default MessageEditAction editMessageComponentsById(@Nonnull String messageId, @ * If this is a {@link GuildMessageChannel GuildMessageChannel} and this account does not have * {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} * or {@link net.dv8tion.jda.api.Permission#MESSAGE_SEND Permission.MESSAGE_SEND} + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} */ @@ -3140,6 +3260,8 @@ default MessageEditAction editMessageComponentsById(long messageId, @Nonnull Lay * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} that can be used to further update the message * @@ -3191,6 +3313,8 @@ default MessageEditAction editMessageAttachmentsById(@Nonnull String messageId, * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} that can be used to further update the message * @@ -3242,6 +3366,8 @@ default MessageEditAction editMessageAttachmentsById(@Nonnull String messageId, * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} that can be used to further update the message * @@ -3292,6 +3418,8 @@ default MessageEditAction editMessageAttachmentsById(long messageId, @Nonnull Co * * @throws IllegalArgumentException * If null is provided + * @throws net.dv8tion.jda.api.exceptions.DetachedEntityException + * if the bot {@link Guild#isDetached() isn't in the guild}. * * @return {@link MessageEditAction} that can be used to further update the message * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/unions/ChannelUnion.java b/src/main/java/net/dv8tion/jda/api/entities/channel/unions/ChannelUnion.java index 9bb7ba1821..61ba762d54 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/unions/ChannelUnion.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/unions/ChannelUnion.java @@ -32,6 +32,7 @@ *
    This interface represents the follow concrete channel types: *
      *
    • {@link PrivateChannel}
    • + *
    • {@link GroupChannel}
    • *
    • {@link TextChannel}
    • *
    • {@link NewsChannel}
    • *
    • {@link ThreadChannel}
    • @@ -66,6 +67,27 @@ public interface ChannelUnion extends Channel @Nonnull PrivateChannel asPrivateChannel(); + /** + * Casts this union to a {@link GroupChannel}. + * This method exists for developer discoverability. + * + *

      Note: This is effectively equivalent to using the cast operator: + *

      
      +     * //These are the same!
      +     * GroupChannel channel = union.asGroupChannel();
      +     * GroupChannel channel2 = (GroupChannel) union;
      +     * 
      + * + * You can use {@link #getType()} to see if the channel is of type {@link ChannelType#GROUP} to validate + * whether you can call this method in addition to normal instanceof checks: channel instanceof GroupChannel + * + * @throws IllegalStateException + * If the channel represented by this union is not actually a {@link GroupChannel}. + * + * @return The channel as a {@link GroupChannel} + */ + @Nonnull + GroupChannel asGroupChannel(); /** * Casts this union to a {@link TextChannel}. diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/unions/MessageChannelUnion.java b/src/main/java/net/dv8tion/jda/api/entities/channel/unions/MessageChannelUnion.java index e9148d18b1..886ef53761 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/unions/MessageChannelUnion.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/unions/MessageChannelUnion.java @@ -38,6 +38,7 @@ *
    • {@link StageChannel}
    • *
    • {@link ThreadChannel}
    • *
    • {@link PrivateChannel}
    • + *
    • {@link GroupChannel}
    • *
    */ public interface MessageChannelUnion extends MessageChannel @@ -64,6 +65,28 @@ public interface MessageChannelUnion extends MessageChannel @Nonnull PrivateChannel asPrivateChannel(); + /** + * Casts this union to a {@link GroupChannel}. + * This method exists for developer discoverability. + * + *

    Note: This is effectively equivalent to using the cast operator: + *

    
    +     * //These are the same!
    +     * GroupChannel channel = union.asGroupChannel();
    +     * GroupChannel channel2 = (GroupChannel) union;
    +     * 
    + * + * You can use {@link #getType()} to see if the channel is of type {@link ChannelType#GROUP} to validate + * whether you can call this method in addition to normal instanceof checks: channel instanceof GroupChannel + * + * @throws IllegalStateException + * If the channel represented by this union is not actually a {@link GroupChannel}. + * + * @return The channel as a {@link GroupChannel} + */ + @Nonnull + GroupChannel asGroupChannel(); + /** * Casts this union to a {@link TextChannel}. * This method exists for developer discoverability. diff --git a/src/main/java/net/dv8tion/jda/api/entities/detached/IDetachableEntity.java b/src/main/java/net/dv8tion/jda/api/entities/detached/IDetachableEntity.java new file mode 100644 index 0000000000..16af4d9797 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/detached/IDetachableEntity.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.detached; + +/** + * Represents an entity which might not be known by the bot. + * It is mostly limited to user-installed interactions, + * where the bot {@link net.dv8tion.jda.api.entities.Guild#isDetached() isn't in the guild}, + * and in group DMs. + *
    Some information may be unavailable on detached entities, + * and most {@link net.dv8tion.jda.api.requests.RestAction RestActions} will fail with a {@link net.dv8tion.jda.api.exceptions.DetachedEntityException DetachedEntityException}. + */ +public interface IDetachableEntity +{ + /** + * Whether this entity is detached, i.e., + * if the entity isn't known by the bot, such as unknown guilds, friend DMs, and group DMs. + * + * @return {@code True}, if the entity is detached + */ + boolean isDetached(); +} diff --git a/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java index 24d40d8f20..2460677ea7 100644 --- a/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java @@ -24,7 +24,9 @@ import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.events.Event; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationOwners; import net.dv8tion.jda.api.interactions.Interaction; +import net.dv8tion.jda.api.interactions.InteractionContextType; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -109,6 +111,20 @@ public DiscordLocale getGuildLocale() return interaction.getGuildLocale(); } + @Nonnull + @Override + public InteractionContextType getContext() + { + return interaction.getContext(); + } + + @Nonnull + @Override + public IntegrationOwners getIntegrationOwners() + { + return interaction.getIntegrationOwners(); + } + @Nullable @Override public Member getMember() diff --git a/src/main/java/net/dv8tion/jda/api/exceptions/DetachedEntityException.java b/src/main/java/net/dv8tion/jda/api/exceptions/DetachedEntityException.java new file mode 100644 index 0000000000..ae81673bd9 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/exceptions/DetachedEntityException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.dv8tion.jda.api.exceptions; + +/** + * Indicates that the operation cannot be done on a detached entity. + * + * @see net.dv8tion.jda.api.entities.detached.IDetachableEntity + */ +public class DetachedEntityException extends RuntimeException +{ + /** + * Creates a new DetachedEntityException + */ + public DetachedEntityException() + { + this("Cannot perform action as the bot is not in the guild"); + } + + /** + * Creates a new DetachedEntityException + * + * @param reason + * The reason for this Exception + */ + public DetachedEntityException(String reason) + { + super(reason); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/exceptions/MissingEntityInteractionPermissionsException.java b/src/main/java/net/dv8tion/jda/api/exceptions/MissingEntityInteractionPermissionsException.java new file mode 100644 index 0000000000..c4de6bc4dc --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/exceptions/MissingEntityInteractionPermissionsException.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.dv8tion.jda.api.exceptions; + +/** + * Exception occurring on {@link net.dv8tion.jda.api.entities.detached.IDetachableEntity#isDetached() detached entities}, + * indicating that the permissions could not be checked on this combination of channel and member. + * + *

    Getting/Checking the permissions of a {@link net.dv8tion.jda.api.entities.Member Member} in a given {@link net.dv8tion.jda.api.entities.channel.middleman.GuildChannel GuildChannel}, + * will only work when either: + *

      + *
    • The member is the {@link net.dv8tion.jda.api.interactions.Interaction#getMember() interaction caller}, + * and the channel is the {@link net.dv8tion.jda.api.interactions.Interaction#getGuildChannel() interaction channel} + *
    • + *
    • The member is an interaction option (such as slash command option or a member {@link net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu EntitySelectMenu} value) + * and the channel is the {@link net.dv8tion.jda.api.interactions.Interaction#getGuildChannel() interaction channel} + *
    • + *
    • The member is the {@link net.dv8tion.jda.api.interactions.Interaction#getMember() interaction caller}, and the channel is an interaction option
    • + *
    + */ +public class MissingEntityInteractionPermissionsException extends RuntimeException +{ + /** + * Creates a new MissingEntityInteractionPermissionsException + */ + public MissingEntityInteractionPermissionsException() + { + this("Cannot perform action as the bot is not in the guild"); + } + + /** + * Creates a new MissingEntityInteractionPermissionsException + * + * @param reason + * The reason for this Exception + */ + public MissingEntityInteractionPermissionsException(String reason) + { + super(reason); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/IntegrationOwners.java b/src/main/java/net/dv8tion/jda/api/interactions/IntegrationOwners.java new file mode 100644 index 0000000000..57993cba58 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/interactions/IntegrationOwners.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.interactions; + +import net.dv8tion.jda.api.entities.UserSnowflake; + +import javax.annotation.Nullable; + +/** + * Includes details about the authorizing user or guild for the installation(s) relevant to the interaction. + * For apps installed to a user, it can be used to tell the difference between the authorizing user + * and the user that triggered an interaction (like a message component). + * + * @see Discord Docs about Authorizing Integration Owners Object + */ +public interface IntegrationOwners +{ + /** + * Returns the ID of the authorizing user. + *
    This is not the ID of the interaction caller, + * but rather the ID of the user which started the original interaction. + * + *

    This is only available if the app was installed on the user. + * + * @return the ID of the authorizing user, or {@code null} + */ + @Nullable + UserSnowflake getUserIntegration(); + + /** + * In some conditions, returns the guild ID if the interaction is triggered from a guild, + * or {@code 0} if the interaction is triggered from a DM with the app's bot user. + * + *

    In a guild and in the app's DMs, this is only available if: + *

      + *
    • The command's integration contexts contains {@link IntegrationType#GUILD_INSTALL} and {@link IntegrationType#USER_INSTALL}
    • + *
    • The interaction comes from a component
    • + *
    + * + * @return the guild ID in which the interaction is triggered in, or {@code 0}, or {@code null} + */ + @Nullable + Long getGuildIntegration(); +} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/IntegrationType.java b/src/main/java/net/dv8tion/jda/api/interactions/IntegrationType.java new file mode 100644 index 0000000000..ab891624dc --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/interactions/IntegrationType.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.interactions; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +/** + * Represents how an app was installed, or where a command can be used. + * + * @see Discord docs + */ +public enum IntegrationType +{ + UNKNOWN("-1"), + /** + * Indicates commands can be installed on the guild the application was invited in. + */ + GUILD_INSTALL("0"), + /** + * Indicates commands can be installed on the user inviting the application. + * + *

    Enables using {@link InteractionContextType#GUILD} in guilds the bot isn't in, + * and {@link InteractionContextType#PRIVATE_CHANNEL}. + * + *

    Requirements + *
    This requires the bot to be user-installable, + * see on Your dashboard, + * in the {@code Installation} section, and select the {@code User Install} authorization method. + */ + USER_INSTALL("1"); + + /** + * Contains all integration types + */ + public static final Set ALL = Collections.unmodifiableSet(EnumSet.of(GUILD_INSTALL, USER_INSTALL)); + + private final String key; + + IntegrationType(String key) + { + this.key = key; + } + + /** + * The raw value of this integration type. + * + * @return The raw value + */ + @Nonnull + public String getType() + { + return key; + } + + /** + * Gets the integration type corresponding to the key, + * returns {@link #UNKNOWN} if no entry matches. + * + * @param key + * The key to match against + * + * @return The integration type corresponding to the key + */ + @Nonnull + public static IntegrationType fromKey(@Nonnull String key) + { + for (IntegrationType value : values()) + { + if (value.key.equals(key)) + return value; + } + return UNKNOWN; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java b/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java index 32fbb0d545..b7e2901284 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java @@ -98,6 +98,19 @@ default InteractionType getType() @Nullable Guild getGuild(); + /** + * Whether this interaction happened in a guild the bot is in. + * + * @return {@code true}, if this interaction happened in a guild the bot is in + */ + default boolean hasFullGuild() + { + final Guild guild = getGuild(); + if (guild == null) + return false; + return !guild.isDetached(); + } + /** * Whether this interaction came from a {@link Guild}. *
    This is identical to {@code getGuild() != null} @@ -109,6 +122,18 @@ default boolean isFromGuild() return getGuild() != null; } + /** + * Whether this interaction comes from a command + * which can only be {@link IntegrationType#USER_INSTALL installed on a user}. + * + * @return True, if this interaction is installed only on a user + */ + default boolean isUserInstalledInteractionOnly() + { + final IntegrationOwners owners = getIntegrationOwners(); + return owners.getUserIntegration() != null && owners.getGuildIntegration() == null; + } + /** * The {@link ChannelType} for the channel this interaction came from. *
    If {@link #getChannel()} is null, this returns {@link ChannelType#UNKNOWN}. @@ -240,6 +265,22 @@ default DiscordLocale getGuildLocale() @Nonnull List getEntitlements(); + /** + * Gets the context in which this command was executed. + * + * @return The context in which this command was executed + */ + @Nonnull + InteractionContextType getContext(); + + /** + * Returns the integration owners of this interaction, which depends on how the app was installed. + * + * @return The integration owners of this interaction + */ + @Nonnull + IntegrationOwners getIntegrationOwners(); + /** * Returns the {@link net.dv8tion.jda.api.JDA JDA} instance of this interaction * diff --git a/src/main/java/net/dv8tion/jda/api/interactions/InteractionContextType.java b/src/main/java/net/dv8tion/jda/api/interactions/InteractionContextType.java new file mode 100644 index 0000000000..21db2b3eb3 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/interactions/InteractionContextType.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.interactions; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +/** + * Represents where commands can be used, + * think of it as 'Where can I use this command in the Discord client'. + * + * @see Discord docs + */ +public enum InteractionContextType +{ + UNKNOWN("-1"), + /** + * Allows execution in a guild. + * + *

    Note: Using this command in guilds the bot isn't in + * requires the {@link IntegrationType#USER_INSTALL USER_INSTALL} installation context. + */ + GUILD("0"), + /** + * Allows execution in the bot DMs. + */ + BOT_DM("1"), + /** + * Allows execution in a private channel other than the bot DMs, + * includes friend DMs and Group DMs. + * + *

    Requirements + *
    This requires the {@link IntegrationType#USER_INSTALL USER_INSTALL} installation context. + */ + PRIVATE_CHANNEL("2"); + + /** + * Contains all interaction types + */ + public static final Set ALL = Collections.unmodifiableSet(EnumSet.of(GUILD, BOT_DM, PRIVATE_CHANNEL)); + + private final String key; + + InteractionContextType(String key) + { + this.key = key; + } + + /** + * The raw value of this interaction context. + * + * @return The raw value + */ + @Nonnull + public String getType() + { + return key; + } + + /** + * Gets the interaction context corresponding to the key, + * returns {@link #UNKNOWN} if no entry matches. + * + * @param key + * The key to match against + * + * @return The interaction context corresponding to the key + */ + @Nonnull + public static InteractionContextType fromKey(@Nonnull String key) + { + for (InteractionContextType value : values()) + { + if (value.key.equals(key)) + return value; + } + return UNKNOWN; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/InteractionHook.java b/src/main/java/net/dv8tion/jda/api/interactions/InteractionHook.java index ecc2dae922..7c755b9101 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/InteractionHook.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/InteractionHook.java @@ -17,9 +17,11 @@ package net.dv8tion.jda.api.interactions; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.WebhookClient; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.interactions.callbacks.IMessageEditCallback; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.components.ActionRow; @@ -27,12 +29,15 @@ import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction; import net.dv8tion.jda.api.utils.AttachedFile; +import net.dv8tion.jda.api.utils.FileUpload; import net.dv8tion.jda.api.utils.messages.MessageEditData; import net.dv8tion.jda.internal.interactions.InteractionHookImpl; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; +import java.io.File; +import java.io.InputStream; import java.util.Arrays; import java.util.Collection; @@ -104,11 +109,13 @@ default boolean isExpired() *

    Ephemeral messages have some limitations and will be removed once the user restarts their client. *
    Limitations: *

      - *
    • Cannot contain any files/attachments
    • *
    • Cannot be reacted to
    • - *
    • Cannot be retrieved
    • + *
    • Cannot be {@link net.dv8tion.jda.api.entities.channel.middleman.MessageChannel#retrieveMessageById(long) retrieved by ID}
    • *
    * + * Note: Your message will always appear ephemeral + * if the guild has {@link net.dv8tion.jda.api.Permission#USE_EXTERNAL_APPLICATIONS Permission.USE_EXTERNAL_APPLICATIONS} disabled. + * * @param ephemeral * True if messages should be ephemeral * @@ -151,6 +158,10 @@ default RestAction retrieveOriginal() *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param content @@ -181,6 +192,10 @@ default WebhookMessageEditAction editOriginal(@Nonnull String content) *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param components @@ -211,6 +226,10 @@ default WebhookMessageEditAction editOriginalComponents(@Nonnull Collec *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param components @@ -241,6 +260,10 @@ default WebhookMessageEditAction editOriginalComponents(@Nonnull Layout *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param embeds @@ -271,6 +294,10 @@ default WebhookMessageEditAction editOriginalEmbeds(@Nonnull Collection *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param embeds @@ -301,6 +328,10 @@ default WebhookMessageEditAction editOriginalEmbeds(@Nonnull MessageEmb *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param message @@ -331,6 +362,10 @@ default WebhookMessageEditAction editOriginal(@Nonnull MessageEditData *
    The webhook is no longer available, either it was deleted or in case of interactions it expired. *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} *
    The message for that id does not exist
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param format @@ -351,7 +386,53 @@ default WebhookMessageEditAction editOriginalFormat(@Nonnull String for return editOriginal(String.format(format, args)); } - + /** + * Edit the source message sent by this interaction. + *
    For {@link IMessageEditCallback#editComponents(Collection)} and {@link IMessageEditCallback#deferEdit()} this will be the message the components are attached to. + * For {@link IReplyCallback#deferReply()} and {@link IReplyCallback#reply(String)} this will be the reply message instead. + * + *

    This method will be delayed until the interaction is acknowledged. + * + *

    The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If any of the provided files is bigger than {@link Guild#getMaxFileSize()}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_ACCESS MISSING_ACCESS} + *
      The request was attempted after the account lost access to the {@link Guild Guild} + * typically due to being kicked or removed, or after {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * was revoked in the {@link GuildMessageChannel}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      The provided {@code messageId} is unknown in this MessageChannel, either due to the id being invalid, or + * the message it referred to has already been deleted. This might also be triggered for ephemeral messages.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_CHANNEL UNKNOWN_CHANNEL} + *
      The request was attempted after the channel was deleted.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * + *

    Resource Handling Note: Once the request is handed off to the requester, for example when you call {@link RestAction#queue()}, + * the requester will automatically clean up all opened files by itself. You are only responsible to close them yourself if it is never handed off properly. + * For instance, if an exception occurs after using {@link FileUpload#fromData(File)}, before calling {@link RestAction#queue()}. + * You can safely use a try-with-resources to handle this, since {@link FileUpload#close()} becomes ineffective once the request is handed off. + * + * @param attachments + * The new attachments of the message (Can be {@link FileUpload FileUploads} or {@link net.dv8tion.jda.api.utils.AttachmentUpdate AttachmentUpdates}) + * + * @throws IllegalArgumentException + * If {@code null} is provided + * + * @return {@link WebhookMessageEditAction} + * + * @see AttachedFile#fromAttachment(Message.Attachment) + * @see FileUpload#fromData(InputStream, String) + */ @Nonnull @CheckReturnValue default WebhookMessageEditAction editOriginalAttachments(@Nonnull Collection attachments) @@ -359,6 +440,53 @@ default WebhookMessageEditAction editOriginalAttachments(@Nonnull Colle return editMessageAttachmentsById("@original", attachments); } + /** + * Edit the source message sent by this interaction. + *
    For {@link IMessageEditCallback#editComponents(Collection)} and {@link IMessageEditCallback#deferEdit()} this will be the message the components are attached to. + * For {@link IReplyCallback#deferReply()} and {@link IReplyCallback#reply(String)} this will be the reply message instead. + * + *

    This method will be delayed until the interaction is acknowledged. + * + *

    The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If any of the provided files is bigger than {@link Guild#getMaxFileSize()}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_ACCESS MISSING_ACCESS} + *
      The request was attempted after the account lost access to the {@link Guild Guild} + * typically due to being kicked or removed, or after {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL} + * was revoked in the {@link GuildMessageChannel}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      The provided {@code messageId} is unknown in this MessageChannel, either due to the id being invalid, or + * the message it referred to has already been deleted. This might also be triggered for ephemeral messages.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_CHANNEL UNKNOWN_CHANNEL} + *
      The request was attempted after the channel was deleted.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * + *

    Resource Handling Note: Once the request is handed off to the requester, for example when you call {@link RestAction#queue()}, + * the requester will automatically clean up all opened files by itself. You are only responsible to close them yourself if it is never handed off properly. + * For instance, if an exception occurs after using {@link FileUpload#fromData(File)}, before calling {@link RestAction#queue()}. + * You can safely use a try-with-resources to handle this, since {@link FileUpload#close()} becomes ineffective once the request is handed off. + * + * @param attachments + * The new attachments of the message (Can be {@link FileUpload FileUploads} or {@link net.dv8tion.jda.api.utils.AttachmentUpdate AttachmentUpdates}) + * + * @throws IllegalArgumentException + * If {@code null} is provided + * + * @return {@link WebhookMessageEditAction} + * + * @see AttachedFile#fromAttachment(Message.Attachment) + * @see FileUpload#fromData(InputStream, String) + */ @Nonnull @CheckReturnValue default WebhookMessageEditAction editOriginalAttachments(@Nonnull AttachedFile... attachments) diff --git a/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java index dbaca131ea..89f2f8bceb 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java @@ -90,11 +90,13 @@ public interface IReplyCallback extends IDeferrableCallback *
    When a message is ephemeral, it will only be visible to the user that used the interaction. *
    Limitations: *

      - *
    • Cannot contain any files/attachments
    • *
    • Cannot be reacted to
    • - *
    • Cannot be retrieved
    • + *
    • Cannot be {@link net.dv8tion.jda.api.entities.channel.middleman.MessageChannel#retrieveMessageById(long) retrieved by ID}
    • *
    * + * Note: Your message will always appear ephemeral + * if the guild has {@link net.dv8tion.jda.api.Permission#USE_EXTERNAL_APPLICATIONS Permission.USE_EXTERNAL_APPLICATIONS} disabled. + * * @param ephemeral * True, if this message should only be visible to the interaction user * diff --git a/src/main/java/net/dv8tion/jda/api/interactions/commands/Command.java b/src/main/java/net/dv8tion/jda/api/interactions/commands/Command.java index 6108372bf4..e920983a3e 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/commands/Command.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/commands/Command.java @@ -21,6 +21,8 @@ import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationMap; import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege; @@ -229,9 +231,28 @@ default OffsetDateTime getTimeModified() *
    Always true for guild commands. * * @return True, if this command is restricted to guilds. + * + * @deprecated Replaced with {@link #getContexts()} */ + @Deprecated boolean isGuildOnly(); + /** + * Gets the contexts in which this command can be executed. + * + * @return The contexts in which this command can be executed + */ + @Nonnull + Set getContexts(); + + /** + * Gets the integration types on which this command can be installed on. + * + * @return The integration types on which this command can be installed on + */ + @Nonnull + Set getIntegrationTypes(); + /** * Whether this command is restricted to NSFW (age-restricted) channels. * diff --git a/src/main/java/net/dv8tion/jda/api/interactions/commands/OptionMapping.java b/src/main/java/net/dv8tion/jda/api/interactions/commands/OptionMapping.java index 078e2950f0..71c3dfbb25 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/commands/OptionMapping.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/commands/OptionMapping.java @@ -27,7 +27,6 @@ import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; -import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.InteractionMentions; import net.dv8tion.jda.internal.utils.EntityString; @@ -59,9 +58,9 @@ public OptionMapping(DataObject data, TLongObjectMap resolved, JDA jda, this.name = data.getString("name"); this.resolved = resolved; if (type == OptionType.STRING) - mentions = new InteractionMentions(getAsString(), resolved, (JDAImpl) jda, (GuildImpl) guild); + mentions = new InteractionMentions(getAsString(), resolved, (JDAImpl) jda, guild); else - mentions = new InteractionMentions("", new TLongObjectHashMap<>(0), (JDAImpl) jda, (GuildImpl) guild); + mentions = new InteractionMentions("", new TLongObjectHashMap<>(0), (JDAImpl) jda, guild); } /** diff --git a/src/main/java/net/dv8tion/jda/api/interactions/commands/build/CommandData.java b/src/main/java/net/dv8tion/jda/api/interactions/commands/build/CommandData.java index e1122a060b..cb22e8dc68 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/commands/build/CommandData.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/commands/build/CommandData.java @@ -17,19 +17,25 @@ package net.dv8tion.jda.api.interactions.commands.build; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationMap; +import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.api.utils.data.SerializableData; import net.dv8tion.jda.internal.interactions.CommandDataImpl; import net.dv8tion.jda.internal.utils.Checks; +import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.localization.LocalizationUtils; import javax.annotation.Nonnull; +import java.util.Arrays; import java.util.Collection; import java.util.Map; +import java.util.Set; /** * Builder for Application Commands. @@ -147,10 +153,67 @@ public interface CommandData extends SerializableData * Whether to restrict this command to guilds * * @return The builder instance, for chaining + * + * @deprecated Replaced with {@link #setContexts(InteractionContextType...)} */ @Nonnull + @Deprecated CommandData setGuildOnly(boolean guildOnly); + /** + * Sets the contexts in which this command can be executed (Default: Guild and Bot DMs). + *
    This only has an effect if this command is registered globally. + * + * @param contexts + * The contexts in which this command can be executed + * + * @return The builder instance, for chaining + */ + @Nonnull + default CommandData setContexts(@Nonnull InteractionContextType... contexts) + { + return setContexts(Arrays.asList(contexts)); + } + + /** + * Sets the contexts in which this command can be executed (Default: Guild and Bot DMs). + *
    This only has an effect if this command is registered globally. + * + * @param contexts + * The contexts in which this command can be executed + * + * @return The builder instance, for chaining + */ + @Nonnull + CommandData setContexts(@Nonnull Collection contexts); + + /** + * Sets the integration types on which this command can be installed on (Default: Guilds). + *
    This only has an effect if this command is registered globally. + * + * @param integrationTypes + * The integration types on which this command can be installed on + * + * @return The builder instance, for chaining + */ + @Nonnull + default CommandData setIntegrationTypes(@Nonnull IntegrationType... integrationTypes) + { + return setIntegrationTypes(Arrays.asList(integrationTypes)); + } + + /** + * Sets the integration types on which this command can be installed on (Default: Guilds). + *
    This only has an effect if this command is registered globally. + * + * @param integrationTypes + * The integration types on which this command can be installed on + * + * @return The builder instance, for chaining + */ + @Nonnull + CommandData setIntegrationTypes(@Nonnull Collection integrationTypes); + /** * Sets whether this command should only be usable in NSFW (age-restricted) channels. *
    Default: false @@ -208,9 +271,28 @@ public interface CommandData extends SerializableData *
    Always true for guild commands. * * @return True, if this command is restricted to guilds. + * + * @deprecated Replaced with {@link #getContexts()} */ + @Deprecated boolean isGuildOnly(); + /** + * Gets the contexts in which this command can be executed. + * + * @return The contexts in which this command can be executed + */ + @Nonnull + Set getContexts(); + + /** + * Gets the integration types on which this command can be installed on. + * + * @return The integration types on which this command can be installed on + */ + @Nonnull + Set getIntegrationTypes(); + /** * Whether this command should only be usable in NSFW (age-restricted) channels * @@ -241,7 +323,8 @@ static CommandData fromCommand(@Nonnull Command command) { final CommandDataImpl data = new CommandDataImpl(command.getType(), command.getName()); return data.setDefaultPermissions(command.getDefaultPermissions()) - .setGuildOnly(command.isGuildOnly()) + .setContexts(command.getContexts()) + .setIntegrationTypes(command.getIntegrationTypes()) .setNSFW(command.isNSFW()) .setNameLocalizations(command.getNameLocalizations().toMap()) .setDescriptionLocalizations(command.getDescriptionLocalizations().toMap()); @@ -282,7 +365,12 @@ static CommandData fromData(@Nonnull DataObject object) data.setDefaultPermissions(defaultPermissions == 0 ? DefaultMemberPermissions.DISABLED : DefaultMemberPermissions.enabledFor(defaultPermissions)); } - data.setGuildOnly(!object.getBoolean("dm_permission", true)); + data.setContexts(object.getArray("contexts").stream(DataArray::getString) + .map(InteractionContextType::fromKey) + .collect(Helpers.toUnmodifiableEnumSet(InteractionContextType.class))); + data.setIntegrationTypes(object.getArray("integration_types").stream(DataArray::getString) + .map(IntegrationType::fromKey) + .collect(Helpers.toUnmodifiableEnumSet(IntegrationType.class))); data.setNSFW(object.getBoolean("nsfw")); data.setNameLocalizations(LocalizationUtils.mapFromProperty(object, "name_localizations")); data.setDescriptionLocalizations(LocalizationUtils.mapFromProperty(object, "description_localizations")); diff --git a/src/main/java/net/dv8tion/jda/api/interactions/commands/build/SlashCommandData.java b/src/main/java/net/dv8tion/jda/api/interactions/commands/build/SlashCommandData.java index fde42cb574..da61aa9a27 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/commands/build/SlashCommandData.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/commands/build/SlashCommandData.java @@ -18,6 +18,8 @@ import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -27,6 +29,7 @@ import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.interactions.CommandDataImpl; import net.dv8tion.jda.internal.utils.Checks; +import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.localization.LocalizationUtils; import org.jetbrains.annotations.Unmodifiable; @@ -63,8 +66,31 @@ public interface SlashCommandData extends CommandData @Nonnull @Override + @Deprecated SlashCommandData setGuildOnly(boolean guildOnly); + @Nonnull + @Override + default SlashCommandData setContexts(@Nonnull InteractionContextType... contexts) + { + return (SlashCommandData) CommandData.super.setContexts(contexts); + } + + @Nonnull + @Override + SlashCommandData setContexts(@Nonnull Collection contexts); + + @Nonnull + @Override + default SlashCommandData setIntegrationTypes(@Nonnull IntegrationType... integrationTypes) + { + return (SlashCommandData) CommandData.super.setIntegrationTypes(integrationTypes); + } + + @Nonnull + @Override + SlashCommandData setIntegrationTypes(@Nonnull Collection integrationTypes); + @Nonnull @Override SlashCommandData setNSFW(boolean nsfw); @@ -597,6 +623,8 @@ static SlashCommandData fromCommand(@Nonnull Command command) CommandDataImpl data = new CommandDataImpl(command.getName(), command.getDescription()); data.setGuildOnly(command.isGuildOnly()); + data.setContexts(command.getContexts()); + data.setIntegrationTypes(command.getIntegrationTypes()); data.setNSFW(command.isNSFW()); data.setDefaultPermissions(command.getDefaultPermissions()); //Command localizations are unmodifiable, make a copy @@ -646,7 +674,12 @@ static SlashCommandData fromData(@Nonnull DataObject object) String description = object.getString("description"); DataArray options = object.optArray("options").orElseGet(DataArray::empty); CommandDataImpl command = new CommandDataImpl(name, description); - command.setGuildOnly(!object.getBoolean("dm_permission", true)); + command.setContexts(object.getArray("contexts").stream(DataArray::getString) + .map(InteractionContextType::fromKey) + .collect(Helpers.toUnmodifiableEnumSet(InteractionContextType.class))); + command.setIntegrationTypes(object.getArray("integration_types").stream(DataArray::getString) + .map(IntegrationType::fromKey) + .collect(Helpers.toUnmodifiableEnumSet(IntegrationType.class))); command.setNSFW(object.getBoolean("nsfw")); command.setDefaultPermissions( diff --git a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java index ec98832255..6727b36fbf 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java +++ b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java @@ -142,6 +142,7 @@ public enum ErrorResponse FORUM_POST_TAG_REQUIRED( 40067, "A tag is required to create a forum post in this channel"), DUPLICATE_RESOURCE_ENTITLEMENT( 40074, "An entitlement has already been granted for this resource"), CLOUDFLARE_BLOCKED_REQUEST( 40333, "Cloudflare is blocking your request. This can often be resolved by setting a proper User Agent"), + MAX_FOLLOW_UP_MESSAGES_HIT( 40094, "This interaction has hit the maximum number of follow up messages"), MISSING_ACCESS( 50001, "Missing Access"), INVALID_ACCOUNT_TYPE( 50002, "Invalid Account Type"), INVALID_DM_ACTION( 50003, "Cannot execute action on a DM channel"), diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandCreateAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandCreateAction.java index a55b648810..b4588603ba 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandCreateAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandCreateAction.java @@ -17,6 +17,8 @@ package net.dv8tion.jda.api.requests.restaction; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -166,9 +168,36 @@ default CommandCreateAction addSubcommandGroups(@Nonnull Collection contexts); + + @Nonnull + @Override + @CheckReturnValue + default CommandCreateAction setIntegrationTypes(@Nonnull IntegrationType... integrationTypes) + { + return (CommandCreateAction) SlashCommandData.super.setIntegrationTypes(integrationTypes); + } + + @Nonnull + @Override + @CheckReturnValue + CommandCreateAction setIntegrationTypes(@Nonnull Collection integrationTypes); + @Nonnull @Override CommandCreateAction setNSFW(boolean nsfw); diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandEditAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandEditAction.java index 8261eb90c2..9e41246761 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandEditAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/CommandEditAction.java @@ -16,6 +16,8 @@ package net.dv8tion.jda.api.requests.restaction; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -26,6 +28,7 @@ import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Arrays; import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; @@ -96,11 +99,72 @@ public interface CommandEditAction extends RestAction * Whether to restrict this command to guilds * * @return The CommandEditAction instance, for chaining + * + * @deprecated Replaced with {@link #setContexts(InteractionContextType...)} */ @Nonnull + @Deprecated @CheckReturnValue CommandEditAction setGuildOnly(boolean guildOnly); + /** + * Sets the contexts in which this command can be executed (Default: Guild and Bot DMs). + *
    This only has an effect if this command is registered globally. + * + * @param contexts + * The contexts in which this command can be executed + * + * @return The builder instance, for chaining + */ + @Nonnull + @CheckReturnValue + default CommandEditAction setContexts(@Nonnull InteractionContextType... contexts) + { + return setContexts(Arrays.asList(contexts)); + } + + /** + * Sets the contexts in which this command can be executed (Default: Guild and Bot DMs). + *
    This only has an effect if this command is registered globally. + * + * @param contexts + * The contexts in which this command can be executed + * + * @return The builder instance, for chaining + */ + @Nonnull + @CheckReturnValue + CommandEditAction setContexts(@Nonnull Collection contexts); + + /** + * Sets the integration types on which this command can be installed on (Default: Guilds). + *
    This only has an effect if this command is registered globally. + * + * @param integrationTypes + * The integration types on which this command can be installed on + * + * @return The builder instance, for chaining + */ + @Nonnull + @CheckReturnValue + default CommandEditAction setIntegrationTypes(@Nonnull IntegrationType... integrationTypes) + { + return setIntegrationTypes(Arrays.asList(integrationTypes)); + } + + /** + * Sets the integration types on which this command can be installed on (Default: Guilds). + *
    This only has an effect if this command is registered globally. + * + * @param integrationTypes + * The integration types on which this command can be installed on + * + * @return The builder instance, for chaining + */ + @Nonnull + @CheckReturnValue + CommandEditAction setIntegrationTypes(@Nonnull Collection integrationTypes); + /** * Sets whether this command should only be usable in NSFW (age-restricted) channels. *
    Default: false diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/WebhookMessageCreateAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/WebhookMessageCreateAction.java index 2f73adf10f..93066a4690 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/WebhookMessageCreateAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/WebhookMessageCreateAction.java @@ -47,7 +47,7 @@ public interface WebhookMessageCreateAction extends MessageCreateRequestLimitations: *
      *
    • Cannot be reacted to
    • - *
    • Cannot be retrieved
    • + *
    • Cannot be {@link net.dv8tion.jda.api.entities.channel.middleman.MessageChannel#retrieveMessageById(long) retrieved by ID}
    • *
    * *

    This only works on {@link InteractionHook InteractionHooks}! @@ -55,6 +55,9 @@ public interface WebhookMessageCreateAction extends MessageCreateRequestNote: Your message will always appear ephemeral + * if the guild has {@link net.dv8tion.jda.api.Permission#USE_EXTERNAL_APPLICATIONS Permission.USE_EXTERNAL_APPLICATIONS} disabled. + * * @param ephemeral * True, if this message should be invisible for other users * diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/ReplyCallbackAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/ReplyCallbackAction.java index c1d8237928..4403ae6bb4 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/ReplyCallbackAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/ReplyCallbackAction.java @@ -40,11 +40,13 @@ public interface ReplyCallbackAction extends InteractionCallbackActionEphemeral messages have some limitations and will be removed once the user restarts their client. *
    Limitations: *

      - *
    • Cannot contain any files/attachments
    • *
    • Cannot be reacted to
    • - *
    • Cannot be retrieved
    • + *
    • Cannot be {@link net.dv8tion.jda.api.entities.channel.middleman.MessageChannel#retrieveMessageById(long) retrieved by ID}
    • *
    * + * Note: Your message will always appear ephemeral + * if the guild has {@link net.dv8tion.jda.api.Permission#USE_EXTERNAL_APPLICATIONS Permission.USE_EXTERNAL_APPLICATIONS} disabled. + * * @param ephemeral * True, if this message should be invisible for other users * diff --git a/src/main/java/net/dv8tion/jda/internal/entities/AbstractEntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/AbstractEntityBuilder.java new file mode 100644 index 0000000000..214b58e60f --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/AbstractEntityBuilder.java @@ -0,0 +1,247 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities; + +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.RoleIcon; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPostContainerMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.*; +import net.dv8tion.jda.internal.entities.mixin.MemberMixin; +import net.dv8tion.jda.internal.entities.mixin.RoleMixin; +import net.dv8tion.jda.internal.utils.Helpers; +import net.dv8tion.jda.internal.utils.UnlockHook; +import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; + +public abstract class AbstractEntityBuilder +{ + protected final JDAImpl api; + + AbstractEntityBuilder(JDAImpl api) + { + this.api = api; + } + + public JDAImpl getJDA() + { + return api; + } + + protected void configureCategory(DataObject json, CategoryMixin channel) + { + channel + .setName(json.getString("name")) + .setPosition(json.getInt("position")); + } + + protected void configureTextChannel(DataObject json, TextChannelMixin channel) + { + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setLatestMessageIdLong(json.getLong("last_message_id", 0)) + .setName(json.getString("name")) + .setTopic(json.getString("topic", null)) + .setPosition(json.getInt("position")) + .setNSFW(json.getBoolean("nsfw")) + .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)); + } + + protected void configureNewsChannel(DataObject json, NewsChannelMixin channel) + { + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setLatestMessageIdLong(json.getLong("last_message_id", 0)) + .setName(json.getString("name")) + .setTopic(json.getString("topic", null)) + .setPosition(json.getInt("position")) + .setNSFW(json.getBoolean("nsfw")); + } + + protected void configureVoiceChannel(DataObject json, VoiceChannelMixin channel) + { + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setLatestMessageIdLong(json.getLong("last_message_id", 0)) + .setName(json.getString("name")) + .setStatus(json.getString("status", "")) + .setPosition(json.getInt("position")) + .setUserLimit(json.getInt("user_limit")) + .setNSFW(json.getBoolean("nsfw")) + .setBitrate(json.getInt("bitrate")) + .setRegion(json.getString("rtc_region", null)) +// .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)); + } + + protected void configureStageChannel(DataObject json, StageChannelMixin channel) + { + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setLatestMessageIdLong(json.getLong("last_message_id", 0)) + .setName(json.getString("name")) + .setPosition(json.getInt("position")) + .setBitrate(json.getInt("bitrate")) + .setUserLimit(json.getInt("user_limit", 0)) + .setNSFW(json.getBoolean("nsfw")) + .setRegion(json.getString("rtc_region", null)) +// .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)); + } + + protected void configureThreadChannel(DataObject json, ThreadChannelMixin channel) + { + DataObject threadMetadata = json.getObject("thread_metadata"); + + channel + .setName(json.getString("name")) + .setFlags(json.getInt("flags", 0)) + .setOwnerId(json.getLong("owner_id")) + .setMemberCount(json.getInt("member_count")) + .setMessageCount(json.getInt("message_count")) + .setTotalMessageCount(json.getInt("total_message_count", 0)) + .setLatestMessageIdLong(json.getLong("last_message_id", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)) + .setLocked(threadMetadata.getBoolean("locked")) + .setArchived(threadMetadata.getBoolean("archived")) + .setInvitable(threadMetadata.getBoolean("invitable")) + .setArchiveTimestamp(Helpers.toTimestamp(threadMetadata.getString("archive_timestamp"))) + .setCreationTimestamp(threadMetadata.isNull("create_timestamp") ? 0 : Helpers.toTimestamp(threadMetadata.getString("create_timestamp"))) + .setAutoArchiveDuration(ThreadChannel.AutoArchiveDuration.fromKey(threadMetadata.getInt("auto_archive_duration"))); + } + + protected void configureForumChannel(DataObject json, ForumChannelMixin channel) + { + if (api.isCacheFlagSet(CacheFlag.FORUM_TAGS)) + { + DataArray tags = json.getArray("available_tags"); + for (int i = 0; i < tags.length(); i++) + createForumTag(channel, tags.getObject(i), i); + } + + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setFlags(json.getInt("flags", 0)) + .setDefaultReaction(json.optObject("default_reaction_emoji").orElse(null)) + .setDefaultSortOrder(json.getInt("default_sort_order", -1)) + .setDefaultLayout(json.getInt("default_forum_layout", -1)) + .setName(json.getString("name")) + .setTopic(json.getString("topic", null)) + .setPosition(json.getInt("position")) + .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)) + .setNSFW(json.getBoolean("nsfw")); + } + + protected void configureMediaChannel(DataObject json, MediaChannelMixin channel) + { + if (api.isCacheFlagSet(CacheFlag.FORUM_TAGS)) + { + DataArray tags = json.getArray("available_tags"); + for (int i = 0; i < tags.length(); i++) + createForumTag(channel, tags.getObject(i), i); + } + + channel + .setParentCategory(json.getLong("parent_id", 0)) + .setFlags(json.getInt("flags", 0)) + .setDefaultReaction(json.optObject("default_reaction_emoji").orElse(null)) + .setDefaultSortOrder(json.getInt("default_sort_order", -1)) + .setName(json.getString("name")) + .setTopic(json.getString("topic", null)) + .setPosition(json.getInt("position")) + .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) + .setSlowmode(json.getInt("rate_limit_per_user", 0)) + .setNSFW(json.getBoolean("nsfw")); + } + + public ForumTagImpl createForumTag(IPostContainerMixin channel, DataObject json, int index) + { + final long id = json.getUnsignedLong("id"); + SortedSnowflakeCacheViewImpl cache = channel.getAvailableTagCache(); + ForumTagImpl tag = (ForumTagImpl) cache.get(id); + + if (tag == null) + { + try (UnlockHook lock = cache.writeLock()) + { + tag = new ForumTagImpl(id); + cache.getMap().put(id, tag); + } + } + + tag.setName(json.getString("name")) + .setModerated(json.getBoolean("moderated")) + .setEmoji(json) + .setPosition(index); + return tag; + } + + protected void configurePrivateChannel(DataObject json, PrivateChannelMixin channel) + { + channel.setLatestMessageIdLong(json.getLong("last_message_id", 0)); + } + + protected void configureMember(DataObject memberJson, MemberMixin member) + { + member.setNickname(memberJson.getString("nick", null)); + member.setAvatarId(memberJson.getString("avatar", null)); + if (!memberJson.isNull("flags")) + member.setFlags(memberJson.getInt("flags")); + + long boostTimestamp = memberJson.isNull("premium_since") + ? 0 + : Helpers.toTimestamp(memberJson.getString("premium_since")); + member.setBoostDate(boostTimestamp); + + long timeOutTimestamp = memberJson.isNull("communication_disabled_until") + ? 0 + : Helpers.toTimestamp(memberJson.getString("communication_disabled_until")); + member.setTimeOutEnd(timeOutTimestamp); + + if (!memberJson.isNull("pending")) + member.setPending(memberJson.getBoolean("pending")); + + if (!memberJson.isNull("joined_at")) + member.setJoinDate(Helpers.toTimestamp(memberJson.getString("joined_at"))); + } + + protected void configureRole(DataObject roleJson, RoleMixin role, long id) + { + final int color = roleJson.getInt("color"); + role.setName(roleJson.getString("name")) + .setRawPosition(roleJson.getInt("position")) + .setRawPermissions(roleJson.getLong("permissions")) + .setManaged(roleJson.getBoolean("managed")) + .setHoisted(roleJson.getBoolean("hoist")) + .setColor(color == 0 ? Role.DEFAULT_COLOR_RAW : color) + .setMentionable(roleJson.getBoolean("mentionable")) + .setTags(roleJson.optObject("tags").orElseGet(DataObject::empty)); + + final String iconId = roleJson.getString("icon", null); + final String emoji = roleJson.getString("unicode_emoji", null); + if (iconId == null && emoji == null) + role.setIcon(null); + else + role.setIcon(new RoleIcon(iconId, emoji, id)); + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/ApplicationInfoImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/ApplicationInfoImpl.java index c7bd9b81a1..9b7a4123a1 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/ApplicationInfoImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/ApplicationInfoImpl.java @@ -21,15 +21,13 @@ import net.dv8tion.jda.api.entities.ApplicationInfo; import net.dv8tion.jda.api.entities.ApplicationTeam; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.interactions.IntegrationType; import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.EntityString; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; +import java.util.*; public class ApplicationInfoImpl implements ApplicationInfo { @@ -53,12 +51,14 @@ public class ApplicationInfoImpl implements ApplicationInfo private final String customAuthUrl; private final long defaultAuthUrlPerms; private final List defaultAuthUrlScopes; + private final Map integrationTypesConfig; private String scopes = "bot"; public ApplicationInfoImpl(JDA api, String description, boolean doesBotRequireCodeGrant, String iconId, long id, long flags, - boolean isBotPublic, String name, String termsOfServiceUrl, String privacyPolicyUrl, User owner, ApplicationTeam team, - List tags, List redirectUris, String interactionsEndpointUrl, String roleConnectionsVerificationUrl, - String customAuthUrl, long defaultAuthUrlPerms, List defaultAuthUrlScopes) + boolean isBotPublic, String name, String termsOfServiceUrl, String privacyPolicyUrl, User owner, ApplicationTeam team, + List tags, List redirectUris, String interactionsEndpointUrl, String roleConnectionsVerificationUrl, + String customAuthUrl, long defaultAuthUrlPerms, List defaultAuthUrlScopes, + Map integrationTypesConfig) { this.api = api; this.description = description; @@ -79,6 +79,7 @@ public ApplicationInfoImpl(JDA api, String description, boolean doesBotRequireCo this.customAuthUrl = customAuthUrl; this.defaultAuthUrlPerms = defaultAuthUrlPerms; this.defaultAuthUrlScopes = Collections.unmodifiableList(defaultAuthUrlScopes); + this.integrationTypesConfig = integrationTypesConfig; } @Override @@ -268,10 +269,59 @@ public List getScopes() return defaultAuthUrlScopes; } + @Nonnull + @Override + public Map getIntegrationTypesConfig() + { + return integrationTypesConfig; + } + @Override public String toString() { return new EntityString(this).toString(); } + static class IntegrationTypeConfigurationImpl implements IntegrationTypeConfiguration + { + private final InstallParameters installParameters; + + IntegrationTypeConfigurationImpl(InstallParameters installParameters) + { + this.installParameters = installParameters; + } + + @Nullable + @Override + public InstallParameters getInstallParameters() + { + return installParameters; + } + } + + static class InstallParametersImpl implements InstallParameters + { + private final List scopes; + private final Set permissions; + + InstallParametersImpl(List scopes, Set permissions) + { + this.scopes = Collections.unmodifiableList(scopes); + this.permissions = Collections.unmodifiableSet(permissions); + } + + @Nonnull + @Override + public List getScopes() + { + return scopes; + } + + @Nonnull + @Override + public Set getPermissions() + { + return permissions; + } + } } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index 32578feb36..4704a3671a 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -18,8 +18,8 @@ import gnu.trove.map.TLongObjectMap; import gnu.trove.map.hash.TLongObjectHashMap; -import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.OnlineStatus; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.audit.ActionType; import net.dv8tion.jda.api.audit.AuditLogChange; import net.dv8tion.jda.api.audit.AuditLogEntry; @@ -34,7 +34,6 @@ import net.dv8tion.jda.api.entities.channel.attribute.IThreadContainer; import net.dv8tion.jda.api.entities.channel.attribute.IWebhookContainer; import net.dv8tion.jda.api.entities.channel.concrete.*; -import net.dv8tion.jda.api.entities.channel.forums.ForumTag; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; @@ -54,6 +53,8 @@ import net.dv8tion.jda.api.events.user.update.*; import net.dv8tion.jda.api.exceptions.ParsingException; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.IntegrationOwners; +import net.dv8tion.jda.api.interactions.IntegrationType; import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.utils.cache.CacheFlag; import net.dv8tion.jda.api.utils.cache.CacheView; @@ -62,7 +63,6 @@ import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.channel.concrete.*; import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPermissionContainerMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPostContainerMixin; import net.dv8tion.jda.internal.entities.channel.mixin.middleman.AudioChannelMixin; import net.dv8tion.jda.internal.entities.emoji.CustomEmojiImpl; import net.dv8tion.jda.internal.entities.emoji.RichCustomEmojiImpl; @@ -70,13 +70,13 @@ import net.dv8tion.jda.internal.entities.messages.MessagePollImpl; import net.dv8tion.jda.internal.entities.sticker.*; import net.dv8tion.jda.internal.handle.EventCache; +import net.dv8tion.jda.internal.interactions.IntegrationOwnersImpl; import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.JDALogger; import net.dv8tion.jda.internal.utils.UnlockHook; import net.dv8tion.jda.internal.utils.cache.ChannelCacheViewImpl; import net.dv8tion.jda.internal.utils.cache.MemberCacheViewImpl; import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; -import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.slf4j.Logger; @@ -94,7 +94,7 @@ import java.util.stream.IntStream; import java.util.stream.StreamSupport; -public class EntityBuilder +public class EntityBuilder extends AbstractEntityBuilder { public static final Logger LOG = JDALogger.getLog(EntityBuilder.class); public static final String MISSING_CHANNEL = "MISSING_CHANNEL"; @@ -114,16 +114,9 @@ public class EntityBuilder richGameFields = Collections.unmodifiableSet(tmp); } - protected final JDAImpl api; - - public EntityBuilder(JDA api) - { - this.api = (JDAImpl) api; - } - - public JDAImpl getJDA() + public EntityBuilder(JDAImpl api) { - return api; + super(api); } public SelfUser createSelfUser(DataObject self) @@ -610,23 +603,7 @@ public MemberImpl createMember(GuildImpl guild, DataObject memberJson, DataObjec { // Create a brand new member member = new MemberImpl(guild, user); - member.setNickname(memberJson.getString("nick", null)); - member.setAvatarId(memberJson.getString("avatar", null)); - if (!memberJson.isNull("flags")) - member.setFlags(memberJson.getInt("flags")); - - long boostTimestamp = memberJson.isNull("premium_since") - ? 0 - : Helpers.toTimestamp(memberJson.getString("premium_since")); - member.setBoostDate(boostTimestamp); - - long timeOutTimestamp = memberJson.isNull("communication_disabled_until") - ? 0 - : Helpers.toTimestamp(memberJson.getString("communication_disabled_until")); - member.setTimeOutEnd(timeOutTimestamp); - - if (!memberJson.isNull("pending")) - member.setPending(memberJson.getBoolean("pending")); + configureMember(memberJson, member); Set roles = member.getRoleSet(); for (int i = 0; i < roleArray.length(); i++) { @@ -650,12 +627,6 @@ public MemberImpl createMember(GuildImpl guild, DataObject memberJson, DataObjec updateMember(guild, member, memberJson, roles); } - // Load joined_at if necessary - if (!memberJson.isNull("joined_at") && !member.hasTimeJoined()) - { - member.setJoinDate(Helpers.toTimestamp(memberJson.getString("joined_at"))); - } - // Load voice state and presence if necessary if (voiceStateJson != null && member.getVoiceState() != null) createVoiceState(guild, voiceStateJson, user, member); @@ -1096,10 +1067,7 @@ public Category createCategory(GuildImpl guild, DataObject json, long guildId) } } - channel - .setName(json.getString("name")) - .setPosition(json.getInt("position")); - + configureCategory(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1133,16 +1101,7 @@ public TextChannel createTextChannel(GuildImpl guildObj, DataObject json, long g } } - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)) - .setName(json.getString("name")) - .setTopic(json.getString("topic", null)) - .setPosition(json.getInt("position")) - .setNSFW(json.getBoolean("nsfw")) - .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)); - + configureTextChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1176,14 +1135,7 @@ public NewsChannel createNewsChannel(GuildImpl guildObj, DataObject json, long g } } - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)) - .setName(json.getString("name")) - .setTopic(json.getString("topic", null)) - .setPosition(json.getInt("position")) - .setNSFW(json.getBoolean("nsfw")); - + configureNewsChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1216,19 +1168,7 @@ public VoiceChannel createVoiceChannel(GuildImpl guild, DataObject json, long gu } } - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)) - .setName(json.getString("name")) - .setStatus(json.getString("status", "")) - .setPosition(json.getInt("position")) - .setUserLimit(json.getInt("user_limit")) - .setNSFW(json.getBoolean("nsfw")) - .setBitrate(json.getInt("bitrate")) - .setRegion(json.getString("rtc_region", null)) -// .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)); - + configureVoiceChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1261,18 +1201,7 @@ public StageChannel createStageChannel(GuildImpl guild, DataObject json, long gu } } - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)) - .setName(json.getString("name")) - .setPosition(json.getInt("position")) - .setBitrate(json.getInt("bitrate")) - .setUserLimit(json.getInt("user_limit", 0)) - .setNSFW(json.getBoolean("nsfw")) - .setRegion(json.getString("rtc_region", null)) -// .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)); - + configureStageChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1294,7 +1223,6 @@ public ThreadChannel createThreadChannel(GuildImpl guild, DataObject json, long boolean playbackCache = false; final long id = json.getUnsignedLong("id"); final long parentId = json.getUnsignedLong("parent_id"); - final ChannelType type = ChannelType.fromId(json.getInt("type")); if (guild == null) guild = (GuildImpl) getJDA().getGuildsView().get(guildId); @@ -1312,6 +1240,7 @@ public ThreadChannel createThreadChannel(GuildImpl guild, DataObject json, long UnlockHook vlock = guildThreadView.writeLock(); UnlockHook jlock = threadView.writeLock()) { + final ChannelType type = ChannelType.fromId(json.getInt("type")); channel = new ThreadChannelImpl(id, guild, type); if (modifyCache) { @@ -1321,7 +1250,7 @@ public ThreadChannel createThreadChannel(GuildImpl guild, DataObject json, long } } - DataObject threadMetadata = json.getObject("thread_metadata"); + configureThreadChannel(json, channel); if (!json.isNull("applied_tags") && api.isCacheFlagSet(CacheFlag.FORUM_TAGS)) { @@ -1329,22 +1258,7 @@ public ThreadChannel createThreadChannel(GuildImpl guild, DataObject json, long channel.setAppliedTags(IntStream.range(0, array.length()).mapToLong(array::getUnsignedLong)); } - channel - .setName(json.getString("name")) - .setFlags(json.getInt("flags", 0)) - .setParentChannel(parent) - .setOwnerId(json.getLong("owner_id")) - .setMemberCount(json.getInt("member_count")) - .setMessageCount(json.getInt("message_count")) - .setTotalMessageCount(json.getInt("total_message_count", 0)) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)) - .setLocked(threadMetadata.getBoolean("locked")) - .setArchived(threadMetadata.getBoolean("archived")) - .setInvitable(threadMetadata.getBoolean("invitable")) - .setArchiveTimestamp(Helpers.toTimestamp(threadMetadata.getString("archive_timestamp"))) - .setCreationTimestamp(threadMetadata.isNull("create_timestamp") ? 0 : Helpers.toTimestamp(threadMetadata.getString("create_timestamp"))) - .setAutoArchiveDuration(ThreadChannel.AutoArchiveDuration.fromKey(threadMetadata.getInt("auto_archive_duration"))); + channel.setParentChannel(parent); //If the bot in the thread already, then create a thread member for the bot. if (!json.isNull("member")) @@ -1405,27 +1319,7 @@ public ForumChannel createForumChannel(GuildImpl guild, DataObject json, long gu playbackCache = globalView.put(channel) == null; } } - - if (api.isCacheFlagSet(CacheFlag.FORUM_TAGS)) - { - DataArray tags = json.getArray("available_tags"); - for (int i = 0; i < tags.length(); i++) - createForumTag(channel, tags.getObject(i), i); - } - - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setFlags(json.getInt("flags", 0)) - .setDefaultReaction(json.optObject("default_reaction_emoji").orElse(null)) - .setDefaultSortOrder(json.getInt("default_sort_order", -1)) - .setDefaultLayout(json.getInt("default_forum_layout", -1)) - .setName(json.getString("name")) - .setTopic(json.getString("topic", null)) - .setPosition(json.getInt("position")) - .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)) - .setNSFW(json.getBoolean("nsfw")); - + configureForumChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); @@ -1457,54 +1351,13 @@ public MediaChannel createMediaChannel(GuildImpl guild, DataObject json, long gu playbackCache = globalView.put(channel) == null; } } - - if (api.isCacheFlagSet(CacheFlag.FORUM_TAGS)) - { - DataArray tags = json.getArray("available_tags"); - for (int i = 0; i < tags.length(); i++) - createForumTag(channel, tags.getObject(i), i); - } - - channel - .setParentCategory(json.getLong("parent_id", 0)) - .setFlags(json.getInt("flags", 0)) - .setDefaultReaction(json.optObject("default_reaction_emoji").orElse(null)) - .setDefaultSortOrder(json.getInt("default_sort_order", -1)) - .setName(json.getString("name")) - .setTopic(json.getString("topic", null)) - .setPosition(json.getInt("position")) - .setDefaultThreadSlowmode(json.getInt("default_thread_rate_limit_per_user", 0)) - .setSlowmode(json.getInt("rate_limit_per_user", 0)) - .setNSFW(json.getBoolean("nsfw")); - + configureMediaChannel(json, channel); createOverridesPass(channel, json.getArray("permission_overwrites")); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.CHANNEL, id); return channel; } - public ForumTagImpl createForumTag(IPostContainerMixin channel, DataObject json, int index) - { - final long id = json.getUnsignedLong("id"); - SortedSnowflakeCacheViewImpl cache = channel.getAvailableTagCache(); - ForumTagImpl tag = (ForumTagImpl) cache.get(id); - - if (tag == null) - { - try (UnlockHook lock = cache.writeLock()) - { - tag = new ForumTagImpl(id); - cache.getMap().put(id, tag); - } - } - - tag.setName(json.getString("name")) - .setModerated(json.getBoolean("moderated")) - .setEmoji(json) - .setPosition(index); - return tag; - } - public PrivateChannel createPrivateChannel(DataObject json) { return createPrivateChannel(json, null); @@ -1515,10 +1368,8 @@ public PrivateChannel createPrivateChannel(DataObject json, UserImpl user) final long channelId = json.getUnsignedLong("id"); PrivateChannelImpl channel = (PrivateChannelImpl) api.getPrivateChannelById(channelId); if (channel == null) - { - channel = new PrivateChannelImpl(getJDA(), channelId, user) - .setLatestMessageIdLong(json.getLong("last_message_id", 0)); - } + channel = new PrivateChannelImpl(getJDA(), channelId, user); + configurePrivateChannel(json, channel); UserImpl recipient = user; if (channel.getUser() == null) { @@ -1621,22 +1472,7 @@ public Role createRole(GuildImpl guild, DataObject roleJson, long guildId) playbackCache = roleView.getMap().put(id, role) == null; } } - final int color = roleJson.getInt("color"); - role.setName(roleJson.getString("name")) - .setRawPosition(roleJson.getInt("position")) - .setRawPermissions(roleJson.getLong("permissions")) - .setManaged(roleJson.getBoolean("managed")) - .setHoisted(roleJson.getBoolean("hoist")) - .setColor(color == 0 ? Role.DEFAULT_COLOR_RAW : color) - .setMentionable(roleJson.getBoolean("mentionable")) - .setTags(roleJson.optObject("tags").orElseGet(DataObject::empty)); - - final String iconId = roleJson.getString("icon", null); - final String emoji = roleJson.getString("unicode_emoji", null); - if (iconId == null && emoji == null) - role.setIcon(null); - else - role.setIcon(new RoleIcon(iconId, emoji, id)); + configureRole(roleJson, role, id); if (playbackCache) getJDA().getEventCache().playbackCache(EventCache.Type.ROLE, id); @@ -1660,7 +1496,13 @@ public ReceivedMessage createMessageWithChannel(DataObject json, @Nonnull Messag { // Use channel directly if message is from a known guild channel if (channel instanceof GuildMessageChannel) - return createMessage0(json, channel, (GuildImpl) ((GuildMessageChannel) channel).getGuild(), modifyCache); + { + final GuildMessageChannel messageChannel = (GuildMessageChannel) channel; + return createMessage0(json, channel, messageChannel.isDetached() ? null : (GuildImpl) messageChannel.getGuild(), modifyCache); + } + if (channel instanceof GroupChannel) + return createMessage0(json, channel, null, modifyCache); + // Try to resolve private channel recipient if needed if (channel instanceof PrivateChannel) return createMessageWithLookup(json, null, modifyCache); @@ -1788,11 +1630,10 @@ else if (channel instanceof PrivateChannel) } else { - //Note, while PrivateChannel.getUser() can produce null, this invocation of it WILL NOT produce null - // because when the bot receives a message in a private channel that was _not authored by the bot_ then - // the message had to have come from the user, so that means that we had all the information to build - // the channel properly (or fill-in the missing user info of an existing partial channel) + //PrivateChannel.getUser() can produce null, see docs user = ((PrivateChannel) channel).getUser(); + if (user == null) + user = createUser(author); } } else @@ -1858,6 +1699,10 @@ else if (MISSING_CHANNEL.equals(ex.getMessage())) if (!jsonObject.isNull("interaction")) messageInteraction = createMessageInteraction(guild, jsonObject.getObject("interaction")); + Message.InteractionMetadata interactionMetadata = null; + if (!jsonObject.isNull("interaction_metadata")) + interactionMetadata = createMessageInteractionMetadata(jsonObject.getObject("interaction_metadata")); + // Lazy Mention parsing and caching (includes reply mentions) Mentions mentions = new MessageMentionsImpl( api, guild, content, mentionsEveryone, @@ -1872,7 +1717,7 @@ else if (MISSING_CHANNEL.equals(ex.getMessage())) return new ReceivedMessage(id, channelId, guildId, api, guild, channel, type, messageReference, fromWebhook, applicationId, tts, pinned, content, nonce, user, member, activity, poll, editTime, mentions, reactions, attachments, embeds, stickers, components, flags, - messageInteraction, startedThread, position); + messageInteraction, interactionMetadata, startedThread, position); } private static MessageActivity createMessageActivity(DataObject jsonObject) @@ -2179,6 +2024,21 @@ public Message.Interaction createMessageInteraction(GuildImpl guildImpl, DataObj return new Message.Interaction(id, type, name, user, member); } + public Message.InteractionMetadata createMessageInteractionMetadata(DataObject content) + { + final long id = content.getLong("id"); + final int type = content.getInt("type"); + final User user = createUser(content.getObject("user")); + final IntegrationOwners integrationOwners = new IntegrationOwnersImpl(content.getObject("authorizing_integration_owners")); + final Long originalResponseMessageId = content.isNull("original_response_message_id") ? null : content.getLong("original_response_message_id"); + final Long interactedMessageId = content.isNull("interacted_message_id") ? null : content.getLong("interacted_message_id"); + final Message.InteractionMetadata triggeringInteraction = content.optObject("triggering_interaction_metadata") + .map(this::createMessageInteractionMetadata) + .orElse(null); + + return new Message.InteractionMetadata(id, type, user, integrationOwners, originalResponseMessageId, interactedMessageId, triggeringInteraction); + } + @Nullable public PermissionOverride createPermissionOverride(DataObject override, IPermissionContainerMixin chan) { @@ -2539,9 +2399,30 @@ public ApplicationInfo createApplicationInfo(DataObject object) .collect(Collectors.toList())) .orElse(Collections.emptyList()); + final Optional integrationTypesConfigDict = object.optObject("integration_types_config"); + final Map integrationTypesConfig = integrationTypesConfigDict + .map(d -> { + final Map map = new EnumMap<>(IntegrationType.class); + for (String key : d.keys()) + { + final DataObject value = d.getObject(key); + + final ApplicationInfo.InstallParameters installParameters = value.optObject("oauth2_install_params") + .map(oauth2InstallParams -> new ApplicationInfoImpl.InstallParametersImpl( + oauth2InstallParams.getArray("scopes").stream(DataArray::getString).collect(Collectors.toList()), + Permission.getPermissions(oauth2InstallParams.getLong("permissions")) + )) + .orElse(null); + + map.put(IntegrationType.fromKey(key), new ApplicationInfoImpl.IntegrationTypeConfigurationImpl(installParameters)); + } + return map; + }) + .orElse(Collections.emptyMap()); + return new ApplicationInfoImpl(getJDA(), description, doesBotRequireCodeGrant, iconId, id, flags, isBotPublic, name, termsOfServiceUrl, privacyPolicyUrl, owner, team, tags, redirectUris, interactionsEndpointUrl, - roleConnectionsVerificationUrl, customAuthUrl, defaultAuthUrlPerms, defaultAuthUrlScopes); + roleConnectionsVerificationUrl, customAuthUrl, defaultAuthUrlPerms, defaultAuthUrlScopes, integrationTypesConfig); } public ApplicationTeam createApplicationTeam(DataObject object) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index 2ab78beceb..c3340bbff6 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -147,6 +147,12 @@ public GuildImpl(JDAImpl api, long id) memberPresences = null; } + @Override + public boolean isDetached() + { + return false; + } + public void invalidate() { //Remove everything from global cache diff --git a/src/main/java/net/dv8tion/jda/internal/entities/InteractionEntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/InteractionEntityBuilder.java new file mode 100644 index 0000000000..31d79fce18 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/InteractionEntityBuilder.java @@ -0,0 +1,274 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.*; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.channel.concrete.PrivateChannelImpl; +import net.dv8tion.jda.internal.entities.channel.concrete.detached.*; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.PrivateChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.entities.detached.DetachedMemberImpl; +import net.dv8tion.jda.internal.entities.detached.DetachedRoleImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; +import net.dv8tion.jda.internal.interactions.MemberInteractionPermissions; +import net.dv8tion.jda.internal.utils.JDALogger; +import org.slf4j.Logger; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Optional; +import java.util.stream.Collectors; + +public class InteractionEntityBuilder extends AbstractEntityBuilder +{ + private static final Logger LOG = JDALogger.getLog(InteractionEntityBuilder.class); + + private final EntityBuilder entityBuilder = api.getEntityBuilder(); + private final long interactionChannelId; + private final long interactionUserId; + + public InteractionEntityBuilder(JDAImpl api, long interactionChannelId, long interactionUserId) + { + super(api); + this.interactionChannelId = interactionChannelId; + this.interactionUserId = interactionUserId; + } + + public Guild getOrCreateGuild(DataObject guildJson) + { + final long guildId = guildJson.getUnsignedLong("id"); + final Guild guild = api.getGuildById(guildId); + if (guild != null) + return guild; + + final Optional featuresArray = guildJson.optArray("features"); + final String locale = guildJson.getString("preferred_locale", "en-US"); + + final DetachedGuildImpl detachedGuild = new DetachedGuildImpl(api, guildId); + detachedGuild.setLocale(DiscordLocale.from(locale)); + detachedGuild.setFeatures(featuresArray.map(array -> + array.stream(DataArray::getString) + .map(String::intern) // Prevent allocating the same feature string over and over + .collect(Collectors.toSet()) + ).orElse(Collections.emptySet())); + + return detachedGuild; + } + + public GroupChannel createGroupChannel(DataObject channelData) + { + return new DetachedGroupChannelImpl(api, channelData.getLong("id")) + .setLatestMessageIdLong(channelData.getLong("last_message_id", 0L)) + .setName(channelData.getString("name", "")) + .setOwnerId(channelData.getLong("owner_id")) + .setIcon(channelData.getString("icon", null)); + } + + public GuildChannel createGuildChannel(@Nonnull Guild guild, DataObject channelData) + { + final ChannelType channelType = ChannelType.fromId(channelData.getInt("type")); + switch (channelType) + { + case TEXT: + return createTextChannel(guild, channelData); + case NEWS: + return createNewsChannel(guild, channelData); + case STAGE: + return createStageChannel(guild, channelData); + case VOICE: + return createVoiceChannel(guild, channelData); + case CATEGORY: + return createCategory(guild, channelData); + case FORUM: + return createForumChannel(guild, channelData); + case MEDIA: + return createMediaChannel(guild, channelData); + default: + LOG.debug("Cannot create channel for type " + channelData.getInt("type")); + return null; + } + } + + public Category createCategory(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getCategoryById(json.getLong("id")); + + final long id = json.getLong("id"); + final DetachedCategoryImpl channel = new DetachedCategoryImpl(id, (DetachedGuildImpl) guild); + configureCategory(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public TextChannel createTextChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getTextChannelById(json.getLong("id")); + + final long id = json.getLong("id"); + DetachedTextChannelImpl channel = new DetachedTextChannelImpl(id, (DetachedGuildImpl) guild); + configureTextChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public NewsChannel createNewsChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getNewsChannelById(json.getLong("id")); + + final long id = json.getLong("id"); + DetachedNewsChannelImpl channel = new DetachedNewsChannelImpl(id, (DetachedGuildImpl) guild); + configureNewsChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public VoiceChannel createVoiceChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getVoiceChannelById(json.getLong("id")); + + final long id = json.getLong("id"); + DetachedVoiceChannelImpl channel = new DetachedVoiceChannelImpl(id, (DetachedGuildImpl) guild); + configureVoiceChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public StageChannel createStageChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getStageChannelById(json.getLong("id")); + final long id = json.getLong("id"); + final DetachedStageChannelImpl channel = new DetachedStageChannelImpl(id, (DetachedGuildImpl) guild); + configureStageChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public MediaChannel createMediaChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getMediaChannelById(json.getLong("id")); + + final long id = json.getLong("id"); + final DetachedMediaChannelImpl channel = new DetachedMediaChannelImpl(id, (DetachedGuildImpl) guild); + configureMediaChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public ThreadChannel createThreadChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + { + final ThreadChannel threadChannel = guild.getThreadChannelById(json.getLong("id")); + if (threadChannel != null) + return threadChannel; + else + return entityBuilder.createThreadChannel((GuildImpl) guild, json, guild.getIdLong(), false); + } + + final long id = json.getUnsignedLong("id"); + final ChannelType type = ChannelType.fromId(json.getInt("type")); + DetachedThreadChannelImpl channel = new DetachedThreadChannelImpl(id, (DetachedGuildImpl) guild, type); + configureThreadChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + public ForumChannel createForumChannel(@Nonnull Guild guild, DataObject json) + { + if (!guild.isDetached()) + return guild.getForumChannelById(json.getLong("id")); + + final long id = json.getLong("id"); + final DetachedForumChannelImpl channel = new DetachedForumChannelImpl(id, (DetachedGuildImpl) guild); + configureForumChannel(json, channel); + configureChannelInteractionPermissions(channel, json); + return channel; + } + + private void configureChannelInteractionPermissions(IInteractionPermissionMixin channel, DataObject json) + { + channel.setInteractionPermissions(new ChannelInteractionPermissions(interactionUserId, json.getLong("permissions"))); + } + + public Member createMember(@Nonnull Guild guild, DataObject memberJson) + { + if (!guild.isDetached()) + return entityBuilder.createMember((GuildImpl) guild, memberJson); + + User user = entityBuilder.createUser(memberJson.getObject("user")); + DetachedMemberImpl member = new DetachedMemberImpl((DetachedGuildImpl) guild, user); + configureMember(memberJson, member); + + // Absent outside interactions and in message mentions + if (memberJson.hasKey("permissions")) + member.setInteractionPermissions(new MemberInteractionPermissions(interactionChannelId, memberJson.getLong("permissions"))); + + return member; + } + + public Role createRole(@Nonnull Guild guild, DataObject roleJson) + { + if (!guild.isDetached()) + return guild.getRoleById(roleJson.getLong("id")); + + final long id = roleJson.getLong("id"); + DetachedRoleImpl role = new DetachedRoleImpl(id, (DetachedGuildImpl) guild); + configureRole(roleJson, role, id); + return role; + } + + public PrivateChannel createPrivateChannel(DataObject json, User interactionUser) + { + final long channelId = json.getUnsignedLong("id"); + final DataObject recipientObj = json.optArray("recipients") + .map(d -> d.getObject(0)) + .orElse(null); + + final PrivateChannelMixin channel; + if (recipientObj != null) { + // We only get recipient in Bot DMs and Group DMs + if (interactionUser.getIdLong() == recipientObj.getLong("id")) { + channel = new PrivateChannelImpl(getJDA(), channelId, interactionUser); + } else { + // Friend DMs don't have recipients + throw new IllegalArgumentException("Recipient should only be present in Bot DMs"); + } + } else { + // Friend DMs, no info + channel = new DetachedPrivateChannelImpl(getJDA(), channelId); + } + configurePrivateChannel(json, channel); + return channel; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/InteractionMentions.java b/src/main/java/net/dv8tion/jda/internal/entities/InteractionMentions.java index 337bd233df..67e1e50635 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/InteractionMentions.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/InteractionMentions.java @@ -17,22 +17,20 @@ package net.dv8tion.jda.internal.entities; import gnu.trove.map.TLongObjectMap; -import net.dv8tion.jda.api.entities.IMentionable; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.mentions.AbstractMentions; +import javax.annotation.Nullable; import java.util.regex.Matcher; public class InteractionMentions extends AbstractMentions { protected final TLongObjectMap resolved; - public InteractionMentions(String content, TLongObjectMap resolved, JDAImpl jda, GuildImpl guild) + public InteractionMentions(String content, TLongObjectMap resolved, JDAImpl jda, @Nullable Guild guild) { super(content, jda, guild, false); this.resolved = resolved; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java index cd9b2452e8..bdb2e843b6 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java @@ -29,6 +29,7 @@ import net.dv8tion.jda.api.utils.cache.CacheView; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPermissionContainerMixin; +import net.dv8tion.jda.internal.entities.mixin.MemberMixin; import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.EntityString; import net.dv8tion.jda.internal.utils.Helpers; @@ -43,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; -public class MemberImpl implements Member +public class MemberImpl implements Member, MemberMixin { private final JDAImpl api; private final Set roles = ConcurrentHashMap.newKeySet(); @@ -67,6 +68,12 @@ public MemberImpl(GuildImpl guild, User user) this.voiceState = cacheState ? new GuildVoiceStateImpl(this) : null; } + @Override + public boolean isDetached() + { + return false; + } + public MemberPresenceImpl getPresence() { CacheView.SimpleCacheView presences = guild.getPresenceView(); @@ -270,28 +277,12 @@ public boolean hasPermission(@Nonnull Permission... permissions) return PermissionUtil.checkPermission(this, permissions); } - @Override - public boolean hasPermission(@Nonnull Collection permissions) - { - Checks.notNull(permissions, "Permission Collection"); - - return hasPermission(permissions.toArray(Permission.EMPTY_PERMISSIONS)); - } - @Override public boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Permission... permissions) { return PermissionUtil.checkPermission(channel.getPermissionContainer(), this, permissions); } - @Override - public boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Collection permissions) - { - Checks.notNull(permissions, "Permission Collection"); - - return hasPermission(channel, permissions.toArray(Permission.EMPTY_PERMISSIONS)); - } - @Override public boolean canSync(@Nonnull IPermissionContainer targetChannel, @Nonnull IPermissionContainer syncSource) { @@ -401,42 +392,49 @@ public String getDefaultAvatarId() return user.getDefaultAvatarId(); } + @Override public MemberImpl setNickname(String nickname) { this.nickname = nickname; return this; } + @Override public MemberImpl setAvatarId(String avatarId) { this.avatarId = avatarId; return this; } + @Override public MemberImpl setJoinDate(long joinDate) { this.joinDate = joinDate; return this; } + @Override public MemberImpl setBoostDate(long boostDate) { this.boostDate = boostDate; return this; } + @Override public MemberImpl setTimeOutEnd(long time) { this.timeOutEnd = time; return this; } + @Override public MemberImpl setPending(boolean pending) { this.pending = pending; return this; } + @Override public MemberImpl setFlags(int flags) { this.flags = flags; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/MessageMentionsImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/MessageMentionsImpl.java index 796e337b56..44e3c5de2b 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/MessageMentionsImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/MessageMentionsImpl.java @@ -91,7 +91,7 @@ public synchronized List getMembers() { DataObject mention = userMentionMap.get(iter.next()); if (mention.getBoolean("is_member")) - members.add(0, entityBuilder.createMember(guild, mention)); + members.add(0, entityBuilder.createMember((GuildImpl) guild, mention)); } // Update member cache @@ -151,7 +151,7 @@ protected Member matchMember(Matcher matcher) long id = Long.parseUnsignedLong(matcher.group(1)); DataObject member = userMentionMap.get(id); return member != null && member.getBoolean("is_member") - ? jda.getEntityBuilder().createMember(guild, member) + ? jda.getEntityBuilder().createMember((GuildImpl) guild, member) : null; } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/ReceivedMessage.java b/src/main/java/net/dv8tion/jda/internal/entities/ReceivedMessage.java index da9816ec95..bdbb86cbbd 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/ReceivedMessage.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/ReceivedMessage.java @@ -102,6 +102,7 @@ public class ReceivedMessage implements Message protected final OffsetDateTime editedTime; protected final Mentions mentions; protected final Message.Interaction interaction; + protected final Message.InteractionMetadata interactionMetadata; protected final ThreadChannel startedThread; protected final List reactions; protected final List attachments; @@ -123,7 +124,7 @@ public ReceivedMessage( String content, String nonce, User author, Member member, MessageActivity activity, MessagePoll poll, OffsetDateTime editTime, Mentions mentions, List reactions, List attachments, List embeds, List stickers, List components, - int flags, Message.Interaction interaction, ThreadChannel startedThread, int position) + int flags, Message.Interaction interaction, Message.InteractionMetadata interactionMetadata, ThreadChannel startedThread, int position) { this.id = id; this.channelId = channelId; @@ -151,6 +152,7 @@ public ReceivedMessage( this.components = Collections.unmodifiableList(components); this.flags = flags; this.interaction = interaction; + this.interactionMetadata = interactionMetadata; this.startedThread = startedThread; this.position = position; this.poll = poll; @@ -386,6 +388,13 @@ public Interaction getInteraction() return interaction; } + @Nullable + @Override + public InteractionMetadata getInteractionMetadata() + { + return interactionMetadata; + } + @Override public long getIdLong() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/RoleImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/RoleImpl.java index c7801becba..d2f2e12012 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/RoleImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/RoleImpl.java @@ -30,11 +30,11 @@ import net.dv8tion.jda.api.managers.RoleManager; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; -import net.dv8tion.jda.api.requests.restaction.RoleAction; import net.dv8tion.jda.api.utils.cache.CacheFlag; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPermissionContainerMixin; +import net.dv8tion.jda.internal.entities.mixin.RoleMixin; import net.dv8tion.jda.internal.managers.RoleManagerImpl; import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -45,12 +45,10 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.awt.*; -import java.time.OffsetDateTime; -import java.util.Collection; import java.util.EnumSet; import java.util.Objects; -public class RoleImpl implements Role +public class RoleImpl implements Role, RoleMixin { private final long id; private final JDAImpl api; @@ -75,6 +73,12 @@ public RoleImpl(long id, Guild guild) this.tags = api.isCacheFlagSet(CacheFlag.ROLE_TAGS) ? new RoleTagsImpl() : null; } + @Override + public boolean isDetached() + { + return false; + } + @Override public int getPosition() { @@ -191,14 +195,6 @@ public boolean hasPermission(@Nonnull Permission... permissions) return true; } - @Override - public boolean hasPermission(@Nonnull Collection permissions) - { - Checks.notNull(permissions, "Permission Collection"); - - return hasPermission(permissions.toArray(Permission.EMPTY_PERMISSIONS)); - } - @Override public boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Permission... permissions) { @@ -212,14 +208,6 @@ public boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Permission. return true; } - @Override - public boolean hasPermission(@Nonnull GuildChannel channel, @Nonnull Collection permissions) - { - Checks.notNull(permissions, "Permission Collection"); - - return hasPermission(channel, permissions.toArray(Permission.EMPTY_PERMISSIONS)); - } - @Override public boolean canSync(@Nonnull IPermissionContainer targetChannel, @Nonnull IPermissionContainer syncSource) { @@ -285,20 +273,6 @@ public Guild getGuild() return guild; } - @Nonnull - @Override - public RoleAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - return guild.createRole() - .setColor(color) - .setHoisted(hoisted) - .setMentionable(mentionable) - .setName(name) - .setPermissions(rawPermissions) - .setIcon(icon == null ? null : icon.getEmoji()); // we can only copy the emoji as we don't have access to the Icon instance - } - @Nonnull @Override public RoleManager getManager() @@ -361,9 +335,9 @@ public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof Role)) + if (!(o instanceof RoleImpl)) return false; - Role oRole = (Role) o; + RoleImpl oRole = (RoleImpl) o; return this.getIdLong() == oRole.getIdLong(); } @@ -381,68 +355,51 @@ public String toString() .toString(); } - @Override - public int compareTo(@Nonnull Role r) - { - if (this == r) - return 0; - if (!(r instanceof RoleImpl)) - throw new IllegalArgumentException("Cannot compare different role implementations"); - RoleImpl impl = (RoleImpl) r; - - if (this.guild.getIdLong() != impl.guild.getIdLong()) - throw new IllegalArgumentException("Cannot compare roles that aren't from the same guild!"); - - if (this.getPositionRaw() != r.getPositionRaw()) - return this.getPositionRaw() - r.getPositionRaw(); - - OffsetDateTime thisTime = this.getTimeCreated(); - OffsetDateTime rTime = r.getTimeCreated(); - - //We compare the provided role's time to this's time instead of the reverse as one would expect due to how - // discord deals with hierarchy. The more recent a role was created, the lower its hierarchy ranking when - // it shares the same position as another role. - return rTime.compareTo(thisTime); - } - // -- Setters -- + @Override public RoleImpl setName(String name) { this.name = name; return this; } + @Override public RoleImpl setColor(int color) { this.color = color; return this; } + @Override public RoleImpl setManaged(boolean managed) { this.managed = managed; return this; } + @Override public RoleImpl setHoisted(boolean hoisted) { this.hoisted = hoisted; return this; } + @Override public RoleImpl setMentionable(boolean mentionable) { this.mentionable = mentionable; return this; } + @Override public RoleImpl setRawPermissions(long rawPermissions) { this.rawPermissions = rawPermissions; return this; } + @Override public RoleImpl setRawPosition(int rawPosition) { SortedSnowflakeCacheViewImpl roleCache = (SortedSnowflakeCacheViewImpl) getGuild().getRoleCache(); @@ -451,6 +408,7 @@ public RoleImpl setRawPosition(int rawPosition) return this; } + @Override public RoleImpl setTags(DataObject tags) { if (this.tags == null) @@ -459,6 +417,7 @@ public RoleImpl setTags(DataObject tags) return this; } + @Override public RoleImpl setIcon(RoleIcon icon) { this.icon = icon; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SelectMenuMentions.java b/src/main/java/net/dv8tion/jda/internal/entities/SelectMenuMentions.java index 31ffd9980e..36bf4c8c33 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SelectMenuMentions.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SelectMenuMentions.java @@ -32,6 +32,7 @@ import org.apache.commons.collections4.bag.HashBag; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.*; import java.util.stream.Collectors; @@ -39,7 +40,8 @@ public class SelectMenuMentions implements Mentions { private final DataObject resolved; private final JDAImpl jda; - private final GuildImpl guild; + private final InteractionEntityBuilder interactionEntityBuilder; + private final Guild guild; private final List values; private List cachedUsers; @@ -47,9 +49,10 @@ public class SelectMenuMentions implements Mentions private List cachedRoles; private List cachedChannels; - public SelectMenuMentions(JDAImpl jda, GuildImpl guild, DataObject resolved, DataArray values) + public SelectMenuMentions(JDAImpl jda, InteractionEntityBuilder interactionEntityBuilder, @Nullable Guild guild, DataObject resolved, DataArray values) { this.jda = jda; + this.interactionEntityBuilder = interactionEntityBuilder; this.guild = guild; this.resolved = resolved; this.values = values.stream(DataArray::getString).collect(Collectors.toList()); @@ -96,6 +99,8 @@ public Bag getUsersBag() @Override public List getChannels() { + if (guild == null) + return Collections.emptyList(); if (cachedChannels != null) return cachedChannels; @@ -104,7 +109,18 @@ public List getChannels() return cachedChannels = values.stream() .map(id -> channelMap.optObject(id).orElse(null)) .filter(Objects::nonNull) - .map(json -> jda.getGuildChannelById(ChannelType.fromId(json.getInt("type", -1)), json.getUnsignedLong("id"))) + .map(json -> + { + final ChannelType channelType = ChannelType.fromId(json.getInt("type", -1)); + if (!guild.isDetached()) + return guild.getGuildChannelById(channelType, json.getUnsignedLong("id")); + + // Unknown guilds + if (channelType.isThread()) + return interactionEntityBuilder.createThreadChannel(guild, json); + // Will return null if the type isn't known + return interactionEntityBuilder.createGuildChannel(guild, json); + }) .filter(Objects::nonNull) .collect(Helpers.toUnmodifiableList()); } @@ -137,14 +153,22 @@ public Bag getChannelsBag(@Nonnull Class clazz) @Override public List getRoles() { + if (guild == null) + return Collections.emptyList(); if (cachedRoles != null) return cachedRoles; DataObject roleMap = resolved.optObject("roles").orElseGet(DataObject::empty); return cachedRoles = values.stream() - .filter(roleMap::hasKey) - .map(jda::getRoleById) + .map(id -> roleMap.optObject(id).orElse(null)) + .filter(Objects::nonNull) + .map(json -> + { + if (!guild.isDetached()) + return guild.getRoleById(json.getUnsignedLong("id")); + return interactionEntityBuilder.createRole(guild, json); + }) .filter(Objects::nonNull) .collect(Helpers.toUnmodifiableList()); } @@ -188,21 +212,24 @@ public Bag getSlashCommandsBag() @Override public List getMembers() { + if (guild == null) + return Collections.emptyList(); if (cachedMembers != null) return cachedMembers; DataObject memberMap = resolved.optObject("members").orElseGet(DataObject::empty); DataObject userMap = resolved.optObject("users").orElseGet(DataObject::empty); - EntityBuilder builder = jda.getEntityBuilder(); return cachedMembers = values.stream() .map(id -> memberMap.optObject(id).map(m -> m.put("id", id)).orElse(null)) .filter(Objects::nonNull) .map(json -> json.put("user", userMap.getObject(json.getString("id")))) - .map(json -> builder.createMember(guild, json)) + .map(json -> interactionEntityBuilder.createMember(guild, json)) .filter(Objects::nonNull) - .filter(member -> { - builder.updateMemberCache(member); + .filter(member -> + { + if (!member.isDetached()) + jda.getEntityBuilder().updateMemberCache((MemberImpl) member); return true; }) .collect(Helpers.toUnmodifiableList()); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/AbstractChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/AbstractChannelImpl.java index 6a97f8e0b0..2935b7d45e 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/AbstractChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/AbstractChannelImpl.java @@ -76,6 +76,13 @@ public PrivateChannel asPrivateChannel() return ChannelUtil.safeChannelCast(this, PrivateChannel.class); } + @Nonnull + @Override + public GroupChannel asGroupChannel() + { + return ChannelUtil.safeChannelCast(this, GroupChannel.class); + } + @Nonnull public TextChannel asTextChannel() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/CategoryImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/CategoryImpl.java index 9dcbd3a5a4..b467d0dac6 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/CategoryImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/CategoryImpl.java @@ -17,7 +17,6 @@ package net.dv8tion.jda.internal.entities.channel.concrete; import gnu.trove.map.TLongObjectMap; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.channel.ChannelType; @@ -29,18 +28,15 @@ import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPermissionContainerMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPositionableChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.CategoryMixin; import net.dv8tion.jda.internal.managers.channel.concrete.CategoryManagerImpl; -import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.PermissionUtil; import javax.annotation.Nonnull; public class CategoryImpl extends AbstractGuildChannelImpl implements Category, - IPositionableChannelMixin, - IPermissionContainerMixin + CategoryMixin { private final TLongObjectMap overrides = MiscUtil.newLongMap(); @@ -51,6 +47,19 @@ public CategoryImpl(long id, GuildImpl guild) super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public ChannelType getType() @@ -126,25 +135,6 @@ public CategoryOrderAction modifyVoiceChannelPositions() return getGuild().modifyVoiceChannelPositions(this); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - ChannelAction action = guild.createCategory(name); - if (guild.equals(getGuild())) - { - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public ChannelAction createCopy() diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ForumChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ForumChannelImpl.java index ad478696f7..f0512965a2 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ForumChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ForumChannelImpl.java @@ -18,28 +18,22 @@ import gnu.trove.map.TLongObjectMap; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.channel.ChannelFlag; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel; import net.dv8tion.jda.api.entities.channel.forums.ForumTag; import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion; import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; -import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji; import net.dv8tion.jda.api.managers.channel.concrete.ForumChannelManager; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.*; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.ForumChannelMixin; import net.dv8tion.jda.internal.entities.emoji.CustomEmojiImpl; import net.dv8tion.jda.internal.managers.channel.concrete.ForumChannelManagerImpl; -import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; @@ -49,14 +43,9 @@ import java.util.List; public class ForumChannelImpl extends AbstractGuildChannelImpl - implements ForumChannel, - GuildChannelUnion, - StandardGuildChannelMixin, - IAgeRestrictedChannelMixin, - ISlowmodeChannelMixin, - IWebhookContainerMixin, - IPostContainerMixin, - ITopicChannelMixin + implements ForumChannel, + GuildChannelUnion, + ForumChannelMixin { private final TLongObjectMap overrides = MiscUtil.newLongMap(); private final SortedSnowflakeCacheViewImpl tagCache = new SortedSnowflakeCacheViewImpl<>(ForumTag.class, ForumTag::getName, Comparator.naturalOrder()); @@ -77,6 +66,19 @@ public ForumChannelImpl(long id, GuildImpl guild) super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public ForumChannelManager getManager() @@ -94,38 +96,6 @@ public List getMembers() .collect(Helpers.toUnmodifiableList()); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - ChannelAction action = guild.createForumChannel(name) - .setNSFW(nsfw) - .setTopic(topic) - .setSlowmode(slowmode) - .setAvailableTags(getAvailableTags()) - .setDefaultLayout(Layout.fromKey(defaultLayout)); - if (defaultSortOrder != -1) - action.setDefaultSortOrder(SortOrder.fromKey(defaultSortOrder)); - if (defaultReaction instanceof UnicodeEmoji) - action.setDefaultReaction(defaultReaction); - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - action.setDefaultReaction(defaultReaction); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public EnumSet getFlags() @@ -240,18 +210,21 @@ public ForumChannelImpl setDefaultThreadSlowmode(int defaultThreadSlowmode) return this; } + @Override public ForumChannelImpl setNSFW(boolean nsfw) { this.nsfw = nsfw; return this; } + @Override public ForumChannelImpl setSlowmode(int slowmode) { this.slowmode = slowmode; return this; } + @Override public ForumChannelImpl setTopic(String topic) { this.topic = topic; @@ -284,6 +257,7 @@ public ForumChannelImpl setDefaultSortOrder(int defaultSortOrder) return this; } + @Override public ForumChannelImpl setDefaultLayout(int layout) { this.defaultLayout = layout; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/MediaChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/MediaChannelImpl.java index 7e3af61c2f..eec54cb54b 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/MediaChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/MediaChannelImpl.java @@ -18,28 +18,22 @@ import gnu.trove.map.TLongObjectMap; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.channel.ChannelFlag; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.MediaChannel; import net.dv8tion.jda.api.entities.channel.forums.ForumTag; import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion; import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; -import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji; import net.dv8tion.jda.api.managers.channel.concrete.MediaChannelManager; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.*; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.MediaChannelMixin; import net.dv8tion.jda.internal.entities.emoji.CustomEmojiImpl; import net.dv8tion.jda.internal.managers.channel.concrete.MediaChannelManagerImpl; -import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; @@ -51,12 +45,7 @@ public class MediaChannelImpl extends AbstractGuildChannelImpl implements MediaChannel, GuildChannelUnion, - StandardGuildChannelMixin, - IAgeRestrictedChannelMixin, - ISlowmodeChannelMixin, - IWebhookContainerMixin, - IPostContainerMixin, - ITopicChannelMixin + MediaChannelMixin { private final TLongObjectMap overrides = MiscUtil.newLongMap(); private final SortedSnowflakeCacheViewImpl tagCache = new SortedSnowflakeCacheViewImpl<>(ForumTag.class, ForumTag::getName, Comparator.naturalOrder()); @@ -76,6 +65,19 @@ public MediaChannelImpl(long id, GuildImpl guild) super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public MediaChannelManager getManager() @@ -93,37 +95,6 @@ public List getMembers() .collect(Helpers.toUnmodifiableList()); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - ChannelAction action = guild.createMediaChannel(name) - .setNSFW(nsfw) - .setTopic(topic) - .setSlowmode(slowmode) - .setAvailableTags(getAvailableTags()); - if (defaultSortOrder != -1) - action.setDefaultSortOrder(SortOrder.fromKey(defaultSortOrder)); - if (defaultReaction instanceof UnicodeEmoji) - action.setDefaultReaction(defaultReaction); - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - action.setDefaultReaction(defaultReaction); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public EnumSet getFlags() @@ -247,12 +218,14 @@ public MediaChannelImpl setTopic(String topic) return this; } + @Override public MediaChannelImpl setFlags(int flags) { this.flags = flags; return this; } + @Override public MediaChannelImpl setDefaultReaction(DataObject emoji) { if (emoji != null && !emoji.isNull("emoji_id")) @@ -264,6 +237,7 @@ else if (emoji != null && !emoji.isNull("emoji_name")) return this; } + @Override public MediaChannelImpl setDefaultSortOrder(int defaultSortOrder) { this.defaultSortOrder = defaultSortOrder; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/NewsChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/NewsChannelImpl.java index a1bb4d9850..4d58aaada3 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/NewsChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/NewsChannelImpl.java @@ -17,21 +17,18 @@ package net.dv8tion.jda.internal.entities.channel.concrete; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.Webhook; import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel; import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; import net.dv8tion.jda.api.managers.channel.concrete.NewsChannelManager; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildMessageChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.NewsChannelMixin; import net.dv8tion.jda.internal.managers.channel.concrete.NewsChannelManagerImpl; import net.dv8tion.jda.internal.requests.RestActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -42,13 +39,27 @@ public class NewsChannelImpl extends AbstractStandardGuildMessageChannelImpl implements NewsChannel, - DefaultGuildChannelUnion + DefaultGuildChannelUnion, + NewsChannelMixin { public NewsChannelImpl(long id, GuildImpl guild) { super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public ChannelType getType() @@ -79,28 +90,6 @@ public RestAction follow(@Nonnull String targetChannel }); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - ChannelAction action = guild.createNewsChannel(name).setNSFW(nsfw).setTopic(topic); - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public NewsChannelManager getManager() diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/PrivateChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/PrivateChannelImpl.java index fa303abf98..3890a85428 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/PrivateChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/PrivateChannelImpl.java @@ -24,14 +24,16 @@ import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.MessageChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.PrivateChannelMixin; import net.dv8tion.jda.internal.requests.CompletedRestAction; import net.dv8tion.jda.internal.requests.RestActionImpl; import javax.annotation.Nonnull; import javax.annotation.Nullable; -public class PrivateChannelImpl extends AbstractChannelImpl implements PrivateChannel, MessageChannelMixin +public class PrivateChannelImpl extends AbstractChannelImpl implements + PrivateChannel, + PrivateChannelMixin { private User user; private long latestMessageId; @@ -42,6 +44,12 @@ public PrivateChannelImpl(JDA api, long id, @Nullable User user) this.user = user; } + @Override + public boolean isDetached() + { + return false; + } + @Nonnull @Override public ChannelType getType() @@ -89,14 +97,6 @@ private RestAction retrievePrivateChannel() return new RestActionImpl<>(getJDA(), route, (response, request) -> ((JDAImpl) getJDA()).getEntityBuilder().createPrivateChannel(response.getObject())); } - @Nonnull - @Override - public RestAction delete() - { - Route.CompiledRoute route = Route.Channels.DELETE_CHANNEL.compile(getId()); - return new RestActionImpl<>(getJDA(), route); - } - @Override public long getLatestMessageIdLong() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/StageChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/StageChannelImpl.java index 4c93acb7bb..e148cff661 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/StageChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/StageChannelImpl.java @@ -18,29 +18,21 @@ import gnu.trove.map.TLongObjectMap; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.Region; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.StageInstance; import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.StageChannel; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.managers.channel.concrete.StageChannelManager; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.requests.restaction.StageInstanceAction; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IAgeRestrictedChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IWebhookContainerMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.AudioChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.StageChannelMixin; import net.dv8tion.jda.internal.managers.channel.concrete.StageChannelManagerImpl; import net.dv8tion.jda.internal.requests.RestActionImpl; import net.dv8tion.jda.internal.requests.restaction.StageInstanceActionImpl; @@ -56,11 +48,7 @@ public class StageChannelImpl extends AbstractStandardGuildChannelImpl implements StageChannel, - AudioChannelMixin, - GuildMessageChannelMixin, - IWebhookContainerMixin, - IAgeRestrictedChannelMixin, - ISlowmodeChannelMixin + StageChannelMixin { private final TLongObjectMap connectedMembers = MiscUtil.newLongMap(); @@ -76,6 +64,19 @@ public StageChannelImpl(long id, GuildImpl guild) { super(id, guild); } + + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } @Nonnull @Override @@ -132,35 +133,6 @@ public StageInstanceAction createStageInstance(@Nonnull String topic) return new StageInstanceActionImpl(this).setTopic(topic); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - - ChannelAction action = guild.createStageChannel(name).setBitrate(bitrate); - - if (region != null) - { - action.setRegion(Region.fromKey(region)); - } - - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Override public int getSlowmode() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/TextChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/TextChannelImpl.java index ddcb583224..3522903d94 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/TextChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/TextChannelImpl.java @@ -17,20 +17,15 @@ package net.dv8tion.jda.internal.entities.channel.concrete; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; import net.dv8tion.jda.api.managers.channel.concrete.TextChannelManager; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildMessageChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.TextChannelMixin; import net.dv8tion.jda.internal.managers.channel.concrete.TextChannelManagerImpl; -import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.Helpers; import javax.annotation.Nonnull; @@ -39,7 +34,7 @@ public class TextChannelImpl extends AbstractStandardGuildMessageChannelImpl implements TextChannel, DefaultGuildChannelUnion, - ISlowmodeChannelMixin + TextChannelMixin { private int slowmode; @@ -48,6 +43,19 @@ public TextChannelImpl(long id, GuildImpl guild) super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public ChannelType getType() @@ -70,28 +78,6 @@ public int getSlowmode() return slowmode; } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - ChannelAction action = guild.createTextChannel(name).setNSFW(nsfw).setTopic(topic).setSlowmode(slowmode); - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public TextChannelManager getManager() @@ -99,6 +85,7 @@ public TextChannelManager getManager() return new TextChannelManagerImpl(this); } + @Override public TextChannelImpl setSlowmode(int slowmode) { this.slowmode = slowmode; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ThreadChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ThreadChannelImpl.java index 7dd789a6b3..37465a69ad 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ThreadChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/ThreadChannelImpl.java @@ -40,8 +40,7 @@ import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.ThreadChannelMixin; import net.dv8tion.jda.internal.managers.channel.concrete.ThreadChannelManagerImpl; import net.dv8tion.jda.internal.requests.DeferredRestAction; import net.dv8tion.jda.internal.requests.RestActionImpl; @@ -59,8 +58,7 @@ public class ThreadChannelImpl extends AbstractGuildChannelImpl implements ThreadChannel, - GuildMessageChannelMixin, - ISlowmodeChannelMixin + ThreadChannelMixin { private final ChannelType type; private final CacheView.SimpleCacheView threadMembers = new CacheView.SimpleCacheView<>(ThreadMember.class, null); @@ -87,6 +85,19 @@ public ThreadChannelImpl(long id, GuildImpl guild, ChannelType type) this.type = type; } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) guild; + } + @Nonnull @Override public EnumSet getFlags() @@ -349,6 +360,7 @@ public ThreadChannelImpl setLatestMessageIdLong(long latestMessageId) return this; } + @Override public ThreadChannelImpl setAutoArchiveDuration(AutoArchiveDuration autoArchiveDuration) { this.autoArchiveDuration = autoArchiveDuration; @@ -361,60 +373,70 @@ public ThreadChannelImpl setParentChannel(IThreadContainer channel) return this; } + @Override public ThreadChannelImpl setLocked(boolean locked) { this.locked = locked; return this; } + @Override public ThreadChannelImpl setArchived(boolean archived) { this.archived = archived; return this; } + @Override public ThreadChannelImpl setInvitable(boolean invitable) { this.invitable = invitable; return this; } + @Override public ThreadChannelImpl setArchiveTimestamp(long archiveTimestamp) { this.archiveTimestamp = archiveTimestamp; return this; } + @Override public ThreadChannelImpl setCreationTimestamp(long creationTimestamp) { this.creationTimestamp = creationTimestamp; return this; } + @Override public ThreadChannelImpl setOwnerId(long ownerId) { this.ownerId = ownerId; return this; } + @Override public ThreadChannelImpl setMessageCount(int messageCount) { this.messageCount = messageCount; return this; } + @Override public ThreadChannelImpl setTotalMessageCount(int messageCount) { this.totalMessageCount = Math.max(messageCount, this.messageCount); // If this is 0 we use the older count return this; } + @Override public ThreadChannelImpl setMemberCount(int memberCount) { this.memberCount = memberCount; return this; } + @Override public ThreadChannelImpl setSlowmode(int slowmode) { this.slowmode = slowmode; @@ -429,6 +451,7 @@ public ThreadChannelImpl setAppliedTags(LongStream tags) return this; } + @Override public ThreadChannelImpl setFlags(int flags) { this.flags = flags; @@ -445,7 +468,6 @@ public TLongSet getAppliedTagsSet() return appliedTags; } - public int getRawFlags() { return flags; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/VoiceChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/VoiceChannelImpl.java index 5f28819a10..2825f9224b 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/VoiceChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/VoiceChannelImpl.java @@ -18,26 +18,17 @@ import gnu.trove.map.TLongObjectMap; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.Region; -import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.channel.concrete.Category; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.managers.channel.concrete.VoiceChannelManager; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; -import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildChannelImpl; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IAgeRestrictedChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IWebhookContainerMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.AudioChannelMixin; -import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.VoiceChannelMixin; import net.dv8tion.jda.internal.managers.channel.concrete.VoiceChannelManagerImpl; import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -50,11 +41,7 @@ public class VoiceChannelImpl extends AbstractStandardGuildChannelImpl implements VoiceChannel, - GuildMessageChannelMixin, - AudioChannelMixin, - IWebhookContainerMixin, - IAgeRestrictedChannelMixin, - ISlowmodeChannelMixin + VoiceChannelMixin { private final TLongObjectMap connectedMembers = MiscUtil.newLongMap(); @@ -71,6 +58,19 @@ public VoiceChannelImpl(long id, GuildImpl guild) super(id, guild); } + @Override + public boolean isDetached() + { + return false; + } + + @Nonnull + @Override + public GuildImpl getGuild() + { + return (GuildImpl) super.getGuild(); + } + @Nonnull @Override public ChannelType getType() @@ -109,13 +109,6 @@ public int getSlowmode() return slowmode; } - @Override - public boolean canTalk(@Nonnull Member member) - { - Checks.notNull(member, "Member"); - return member.hasPermission(this, Permission.MESSAGE_SEND); - } - @Override public long getLatestMessageIdLong() { @@ -129,37 +122,6 @@ public List getMembers() return Collections.unmodifiableList(new ArrayList<>(connectedMembers.valueCollection())); } - @Nonnull - @Override - public ChannelAction createCopy(@Nonnull Guild guild) - { - Checks.notNull(guild, "Guild"); - - ChannelAction action = guild.createVoiceChannel(name) - .setBitrate(bitrate) - .setUserlimit(userLimit); - - if (region != null) - { - action.setRegion(Region.fromKey(region)); - } - - if (guild.equals(getGuild())) - { - Category parent = getParentCategory(); - if (parent != null) - action.setParent(parent); - for (PermissionOverride o : overrides.valueCollection()) - { - if (o.isMemberOverride()) - action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - else - action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); - } - } - return action; - } - @Nonnull @Override public VoiceChannelManager getManager() @@ -238,6 +200,7 @@ public VoiceChannelImpl setLatestMessageIdLong(long latestMessageId) return this; } + @Override public VoiceChannelImpl setStatus(String status) { this.status = status; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedCategoryImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedCategoryImpl.java new file mode 100644 index 0000000000..1dbb3096b3 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedCategoryImpl.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.*; +import net.dv8tion.jda.api.managers.channel.concrete.CategoryManager; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.api.requests.restaction.order.CategoryOrderAction; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.CategoryMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; + +import javax.annotation.Nonnull; + +public class DetachedCategoryImpl extends AbstractGuildChannelImpl + implements + Category, + CategoryMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + + private int position; + + public DetachedCategoryImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.CATEGORY; + } + + @Override + public int getPositionRaw() + { + return position; + } + + @Nonnull + @Override + public ChannelAction createTextChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createNewsChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createVoiceChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createStageChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createForumChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createMediaChannel(@Nonnull String name) + { + throw detachedException(); + } + + @Nonnull + @Override + public CategoryOrderAction modifyTextChannelPositions() + { + throw detachedException(); + } + + @Nonnull + @Override + public CategoryOrderAction modifyVoiceChannelPositions() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelAction createCopy() + { + throw detachedException(); + } + + @Nonnull + @Override + public CategoryManager getManager() + { + throw detachedException(); + } + + @Override + public TLongObjectMap getPermissionOverrideMap() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public DetachedCategoryImpl setPosition(int position) + { + this.position = position; + return this; + } + + @Nonnull + @Override + public DetachedCategoryImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedForumChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedForumChannelImpl.java new file mode 100644 index 0000000000..497a6bad7a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedForumChannelImpl.java @@ -0,0 +1,271 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.ChannelFlag; +import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.managers.channel.concrete.ForumChannelManager; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.ForumChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.entities.emoji.CustomEmojiImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; +import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; + +import javax.annotation.Nonnull; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.List; + +public class DetachedForumChannelImpl extends AbstractGuildChannelImpl + implements + ForumChannel, + GuildChannelUnion, + ForumChannelMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + private final SortedSnowflakeCacheViewImpl tagCache = new SortedSnowflakeCacheViewImpl<>(ForumTag.class, ForumTag::getName, Comparator.naturalOrder()); + + private Emoji defaultReaction; + private String topic; + private long parentCategoryId; + private boolean nsfw = false; + private int position; + private int flags; + private int slowmode; + private int defaultSortOrder; + private int defaultLayout; + protected int defaultThreadSlowmode; + + public DetachedForumChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ForumChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public EnumSet getFlags() + { + return ChannelFlag.fromRaw(flags); + } + + @Nonnull + @Override + public SortedSnowflakeCacheViewImpl getAvailableTagCache() + { + return tagCache; + } + + @Override + public TLongObjectMap getPermissionOverrideMap() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public boolean isNSFW() + { + return nsfw; + } + + @Override + public int getPositionRaw() + { + return position; + } + + @Override + public long getParentCategoryIdLong() + { + return parentCategoryId; + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Override + public String getTopic() + { + return topic; + } + + @Override + public EmojiUnion getDefaultReaction() + { + return (EmojiUnion) defaultReaction; + } + + @Override + public int getDefaultThreadSlowmode() + { + return defaultThreadSlowmode; + } + + @Nonnull + @Override + public SortOrder getDefaultSortOrder() + { + return SortOrder.fromKey(defaultSortOrder); + } + + @Nonnull + @Override + public Layout getDefaultLayout() + { + return Layout.fromKey(defaultLayout); + } + + public int getRawFlags() + { + return flags; + } + + public int getRawSortOrder() + { + return defaultSortOrder; + } + + public int getRawLayout() + { + return defaultLayout; + } + + // Setters + + @Override + public DetachedForumChannelImpl setParentCategory(long parentCategoryId) + { + this.parentCategoryId = parentCategoryId; + return this; + } + + @Override + public DetachedForumChannelImpl setPosition(int position) + { + this.position = position; + return this; + } + + @Override + public DetachedForumChannelImpl setDefaultThreadSlowmode(int defaultThreadSlowmode) + { + this.defaultThreadSlowmode = defaultThreadSlowmode; + return this; + } + + @Override + public DetachedForumChannelImpl setNSFW(boolean nsfw) + { + this.nsfw = nsfw; + return this; + } + + @Override + public DetachedForumChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Override + public DetachedForumChannelImpl setTopic(String topic) + { + this.topic = topic; + return this; + } + + @Override + public DetachedForumChannelImpl setFlags(int flags) + { + this.flags = flags; + return this; + } + + @Override + public DetachedForumChannelImpl setDefaultReaction(DataObject emoji) + { + if (emoji != null && !emoji.isNull("emoji_id")) + this.defaultReaction = new CustomEmojiImpl("", emoji.getUnsignedLong("emoji_id"), false); + else if (emoji != null && !emoji.isNull("emoji_name")) + this.defaultReaction = Emoji.fromUnicode(emoji.getString("emoji_name")); + else + this.defaultReaction = null; + return this; + } + + @Override + public DetachedForumChannelImpl setDefaultSortOrder(int defaultSortOrder) + { + this.defaultSortOrder = defaultSortOrder; + return this; + } + + @Override + public DetachedForumChannelImpl setDefaultLayout(int layout) + { + this.defaultLayout = layout; + return this; + } + + @Nonnull + @Override + public DetachedForumChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedGroupChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedGroupChannelImpl.java new file mode 100644 index 0000000000..413073bffe --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedGroupChannelImpl.java @@ -0,0 +1,155 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.UserSnowflake; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.GroupChannelMixin; +import net.dv8tion.jda.internal.entities.detached.mixin.IDetachableEntityMixin; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class DetachedGroupChannelImpl extends AbstractChannelImpl + implements + GroupChannelMixin, + IDetachableEntityMixin +{ + private long latestMessageId; + private UserSnowflake ownerId; + private String icon; + + public DetachedGroupChannelImpl(JDA api, long id) + { + super(id, api); + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.GROUP; + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public UserSnowflake getOwnerId() + { + return ownerId; + } + + @Nullable + public String getIconId() + { + return icon; + } + + @Override + public long getLatestMessageIdLong() + { + return latestMessageId; + } + + @Override + public boolean canTalk() + { + return false; + } + + @Override + public void checkCanAccess() + { + throw detachedException(); + } + + @Override + public void checkCanSendMessage() + { + throw detachedException(); + } + + @Override + public void checkCanSendMessageEmbeds() + { + throw detachedException(); + } + + @Override + public void checkCanSendFiles() + { + throw detachedException(); + } + + @Override + public void checkCanViewHistory() + { + throw detachedException(); + } + + @Override + public void checkCanAddReactions() + { + throw detachedException(); + } + + @Override + public void checkCanRemoveReactions() + { + throw detachedException(); + } + + @Override + public void checkCanControlMessagePins() + { + throw detachedException(); + } + + @Override + public boolean canDeleteOtherUsersMessages() + { + return false; + } + + @Override + public DetachedGroupChannelImpl setLatestMessageIdLong(long latestMessageId) + { + this.latestMessageId = latestMessageId; + return this; + } + + @Override + public DetachedGroupChannelImpl setOwnerId(long ownerId) + { + this.ownerId = UserSnowflake.fromId(ownerId); + return this; + } + + @Override + public DetachedGroupChannelImpl setIcon(@Nullable String icon) + { + this.icon = icon; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedMediaChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedMediaChannelImpl.java new file mode 100644 index 0000000000..f1448304be --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedMediaChannelImpl.java @@ -0,0 +1,251 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.ChannelFlag; +import net.dv8tion.jda.api.entities.channel.concrete.MediaChannel; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.managers.channel.concrete.MediaChannelManager; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.MediaChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.entities.emoji.CustomEmojiImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; +import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl; + +import javax.annotation.Nonnull; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.List; + +public class DetachedMediaChannelImpl extends AbstractGuildChannelImpl + implements + MediaChannel, + GuildChannelUnion, + MediaChannelMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + private final SortedSnowflakeCacheViewImpl tagCache = new SortedSnowflakeCacheViewImpl<>(ForumTag.class, ForumTag::getName, Comparator.naturalOrder()); + + private Emoji defaultReaction; + private String topic; + private long parentCategoryId; + private boolean nsfw = false; + private int position; + private int flags; + private int slowmode; + private int defaultSortOrder; + protected int defaultThreadSlowmode; + + public DetachedMediaChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public MediaChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public EnumSet getFlags() + { + return ChannelFlag.fromRaw(flags); + } + + @Nonnull + @Override + public SortedSnowflakeCacheViewImpl getAvailableTagCache() + { + return tagCache; + } + + @Override + public TLongObjectMap getPermissionOverrideMap() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public boolean isNSFW() + { + return nsfw; + } + + @Override + public int getPositionRaw() + { + return position; + } + + @Override + public long getParentCategoryIdLong() + { + return parentCategoryId; + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Override + public String getTopic() + { + return topic; + } + + @Override + public EmojiUnion getDefaultReaction() + { + return (EmojiUnion) defaultReaction; + } + + @Override + public int getDefaultThreadSlowmode() + { + return defaultThreadSlowmode; + } + + @Nonnull + @Override + public SortOrder getDefaultSortOrder() + { + return SortOrder.fromKey(defaultSortOrder); + } + + public int getRawFlags() + { + return flags; + } + + public int getRawSortOrder() + { + return defaultSortOrder; + } + + // Setters + + @Override + public DetachedMediaChannelImpl setParentCategory(long parentCategoryId) + { + this.parentCategoryId = parentCategoryId; + return this; + } + + @Override + public DetachedMediaChannelImpl setPosition(int position) + { + this.position = position; + return this; + } + + @Override + public DetachedMediaChannelImpl setDefaultThreadSlowmode(int defaultThreadSlowmode) + { + this.defaultThreadSlowmode = defaultThreadSlowmode; + return this; + } + + @Override + public DetachedMediaChannelImpl setNSFW(boolean nsfw) + { + this.nsfw = nsfw; + return this; + } + + @Override + public DetachedMediaChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Override + public DetachedMediaChannelImpl setTopic(String topic) + { + this.topic = topic; + return this; + } + + @Override + public DetachedMediaChannelImpl setFlags(int flags) + { + this.flags = flags; + return this; + } + + @Override + public DetachedMediaChannelImpl setDefaultReaction(DataObject emoji) + { + if (emoji != null && !emoji.isNull("emoji_id")) + this.defaultReaction = new CustomEmojiImpl("", emoji.getUnsignedLong("emoji_id"), false); + else if (emoji != null && !emoji.isNull("emoji_name")) + this.defaultReaction = Emoji.fromUnicode(emoji.getString("emoji_name")); + else + this.defaultReaction = null; + return this; + } + + @Override + public DetachedMediaChannelImpl setDefaultSortOrder(int defaultSortOrder) + { + this.defaultSortOrder = defaultSortOrder; + return this; + } + + @Nonnull + @Override + public DetachedMediaChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedNewsChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedNewsChannelImpl.java new file mode 100644 index 0000000000..97d826741a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedNewsChannelImpl.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Webhook; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel; +import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; +import net.dv8tion.jda.api.managers.channel.concrete.NewsChannelManager; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildMessageChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.NewsChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; + +import javax.annotation.Nonnull; +import java.util.List; + +public class DetachedNewsChannelImpl extends AbstractStandardGuildMessageChannelImpl + implements + NewsChannel, + DefaultGuildChannelUnion, + NewsChannelMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + + public DetachedNewsChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.NEWS; + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction follow(@Nonnull String targetChannelId) + { + throw detachedException(); + } + + @Nonnull + @Override + public NewsChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Nonnull + @Override + public DetachedNewsChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedPrivateChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedPrivateChannelImpl.java new file mode 100644 index 0000000000..8873ca8e41 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedPrivateChannelImpl.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; +import net.dv8tion.jda.api.exceptions.DetachedEntityException; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.PrivateChannelMixin; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class DetachedPrivateChannelImpl extends AbstractChannelImpl implements + PrivateChannel, + PrivateChannelMixin +{ + private long latestMessageId; + + public DetachedPrivateChannelImpl(JDA api, long id) + { + super(id, api); + } + + @Nonnull + @Override + public DetachedEntityException detachedException() + { + return new DetachedEntityException("Cannot perform action in friend DMs"); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.PRIVATE; + } + + @Nullable + @Override + public User getUser() + { + return null; + } + + @Nonnull + @Override + public RestAction retrieveUser() + { + throw detachedException(); + } + + @Nonnull + @Override + public String getName() + { + //don't break or override the contract of @NonNull + return ""; + } + + @Override + public long getLatestMessageIdLong() + { + return latestMessageId; + } + + @Override + public boolean canTalk() + { + return false; + } + + @Override + public void checkCanAccess() { + throw detachedException(); + } + + @Override + public void checkCanSendMessage() { + throw detachedException(); // Should be checked by checkCanAccess first! + } + + @Override + public void checkCanSendMessageEmbeds() { + throw detachedException(); // Should be checked by checkCanSendMessage first! + } + + @Override + public void checkCanSendFiles() { + throw detachedException(); // Should be checked by checkCanSendMessage first! + } + + @Override + public void checkCanViewHistory() { + throw detachedException(); + } + + @Override + public void checkCanAddReactions() { + throw detachedException(); + } + + @Override + public void checkCanRemoveReactions() { + throw detachedException(); + } + + @Override + public void checkCanControlMessagePins() { + throw detachedException(); + } + + @Override + public boolean canDeleteOtherUsersMessages() + { + return false; + } + + @Override + public DetachedPrivateChannelImpl setLatestMessageIdLong(long latestMessageId) + { + this.latestMessageId = latestMessageId; + return this; + } + + @Override + public int hashCode() + { + return Long.hashCode(id); + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + return true; + if (!(obj instanceof DetachedPrivateChannelImpl)) + return false; + DetachedPrivateChannelImpl impl = (DetachedPrivateChannelImpl) obj; + return impl.id == this.id; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedStageChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedStageChannelImpl.java new file mode 100644 index 0000000000..19441824af --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedStageChannelImpl.java @@ -0,0 +1,220 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.StageInstance; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.StageChannel; +import net.dv8tion.jda.api.managers.channel.concrete.StageChannelManager; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.requests.restaction.StageInstanceAction; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.StageChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class DetachedStageChannelImpl extends AbstractStandardGuildChannelImpl + implements + StageChannel, + StageChannelMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + + private String region; + private int bitrate; + private int userlimit; + private int slowmode; + private boolean ageRestricted; + private long latestMessageId; + + public DetachedStageChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.STAGE; + } + + @Override + public int getBitrate() + { + return bitrate; + } + + @Override + public int getUserLimit() + { + return userlimit; + } + + @Nullable + @Override + public String getRegionRaw() + { + return region; + } + + @Nullable + @Override + public StageInstance getStageInstance() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public StageInstanceAction createStageInstance(@Nonnull String topic) + { + throw detachedException(); + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Override + public boolean isNSFW() + { + return ageRestricted; + } + + @Override + public boolean canTalk(@Nonnull Member member) + { + Checks.notNull(member, "Member"); + return member.hasPermission(this, Permission.MESSAGE_SEND); + } + + @Override + public long getLatestMessageIdLong() + { + return latestMessageId; + } + + @Nonnull + @Override + public StageChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction requestToSpeak() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction cancelRequestToSpeak() + { + throw detachedException(); + } + + @Override + public TLongObjectMap getConnectedMembersMap() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public DetachedStageChannelImpl setBitrate(int bitrate) + { + this.bitrate = bitrate; + return this; + } + + @Override + public DetachedStageChannelImpl setUserLimit(int userlimit) + { + this.userlimit = userlimit; + return this; + } + + @Override + public DetachedStageChannelImpl setRegion(String region) + { + this.region = region; + return this; + } + + @Override + public DetachedStageChannelImpl setNSFW(boolean ageRestricted) + { + this.ageRestricted = ageRestricted; + return this; + } + + @Override + public DetachedStageChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Override + public DetachedStageChannelImpl setLatestMessageIdLong(long latestMessageId) + { + this.latestMessageId = latestMessageId; + return this; + } + + @Nonnull + @Override + public DetachedStageChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedTextChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedTextChannelImpl.java new file mode 100644 index 0000000000..1c10f04a84 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedTextChannelImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; +import net.dv8tion.jda.api.managers.channel.concrete.TextChannelManager; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildMessageChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.TextChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; + +import javax.annotation.Nonnull; +import java.util.List; + +public class DetachedTextChannelImpl extends AbstractStandardGuildMessageChannelImpl + implements + TextChannel, + DefaultGuildChannelUnion, + TextChannelMixin, + IInteractionPermissionMixin +{ + private int slowmode; + private ChannelInteractionPermissions interactionPermissions; + + public DetachedTextChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.TEXT; + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Nonnull + @Override + public TextChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public DetachedTextChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Nonnull + @Override + public DetachedTextChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedThreadChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedThreadChannelImpl.java new file mode 100644 index 0000000000..459a9fa0f2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedThreadChannelImpl.java @@ -0,0 +1,395 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.ThreadMember; +import net.dv8tion.jda.api.entities.channel.ChannelFlag; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.attribute.IPermissionContainer; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.entities.channel.unions.IThreadContainerUnion; +import net.dv8tion.jda.api.managers.channel.concrete.ThreadChannelManager; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.requests.restaction.CacheRestAction; +import net.dv8tion.jda.api.requests.restaction.pagination.ThreadMemberPaginationAction; +import net.dv8tion.jda.api.utils.TimeUtil; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.ThreadChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; +import net.dv8tion.jda.internal.utils.Helpers; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.OffsetDateTime; +import java.util.EnumSet; +import java.util.List; + +public class DetachedThreadChannelImpl extends AbstractGuildChannelImpl + implements + ThreadChannel, + ThreadChannelMixin, + IInteractionPermissionMixin +{ + private final ChannelType type; + private ChannelInteractionPermissions interactionPermissions; + + private AutoArchiveDuration autoArchiveDuration; + private boolean locked; + private boolean archived; + private boolean invitable; + private long archiveTimestamp; + private long creationTimestamp; + private long ownerId; + private long latestMessageId; + private int messageCount; + private int totalMessageCount; + private int memberCount; + private int slowmode; + private int flags; + + public DetachedThreadChannelImpl(long id, DetachedGuildImpl guild, ChannelType type) + { + super(id, guild); + this.type = type; + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public EnumSet getFlags() + { + return ChannelFlag.fromRaw(flags); + } + + @Nonnull + @Override + public ChannelType getType() + { + return type; + } + + @Override + public long getLatestMessageIdLong() + { + return latestMessageId; + } + + @Override + public int getMessageCount() + { + return messageCount; + } + + @Override + public int getTotalMessageCount() + { + return totalMessageCount; + } + + @Override + public int getMemberCount() + { + return memberCount; + } + + @Override + public boolean isLocked() + { + return locked; + } + + @Override + public boolean canTalk(@Nonnull Member member) + { + throw detachedException(); + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public IThreadContainerUnion getParentChannel() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getAppliedTags() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveParentMessage() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveStartMessage() + { + throw detachedException(); + } + + @Nonnull + @Override + public IPermissionContainer getPermissionContainer() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getThreadMembers() + { + throw detachedException(); + } + + @Nullable + @Override + public ThreadMember getThreadMemberById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public CacheRestAction retrieveThreadMemberById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public ThreadMemberPaginationAction retrieveThreadMembers() + { + throw detachedException(); + } + + @Override + public long getOwnerIdLong() + { + return ownerId; + } + + @Override + public boolean isArchived() + { + return archived; + } + + @Override + public boolean isInvitable() + { + if (type != ChannelType.GUILD_PRIVATE_THREAD) + throw new UnsupportedOperationException("Only private threads support the concept of invitable."); + + return invitable; + } + + @Nonnull + @Override + public OffsetDateTime getTimeArchiveInfoLastModified() + { + return Helpers.toOffset(archiveTimestamp); + } + + @Nonnull + @Override + public AutoArchiveDuration getAutoArchiveDuration() + { + return autoArchiveDuration; + } + + @Nonnull + @Override + public OffsetDateTime getTimeCreated() + { + return creationTimestamp == 0 ? TimeUtil.getTimeCreated(getIdLong()) : Helpers.toOffset(creationTimestamp); + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Nonnull + @Override + public RestAction join() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction leave() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction addThreadMemberById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction removeThreadMemberById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public ThreadChannelManager getManager() + { + throw detachedException(); + } + + @Override + public void checkCanManage() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public DetachedThreadChannelImpl setLatestMessageIdLong(long latestMessageId) + { + this.latestMessageId = latestMessageId; + return this; + } + + @Override + public DetachedThreadChannelImpl setAutoArchiveDuration(AutoArchiveDuration autoArchiveDuration) + { + this.autoArchiveDuration = autoArchiveDuration; + return this; + } + + @Override + public DetachedThreadChannelImpl setLocked(boolean locked) + { + this.locked = locked; + return this; + } + + @Override + public DetachedThreadChannelImpl setArchived(boolean archived) + { + this.archived = archived; + return this; + } + + @Override + public DetachedThreadChannelImpl setInvitable(boolean invitable) + { + this.invitable = invitable; + return this; + } + + @Override + public DetachedThreadChannelImpl setArchiveTimestamp(long archiveTimestamp) + { + this.archiveTimestamp = archiveTimestamp; + return this; + } + + @Override + public DetachedThreadChannelImpl setCreationTimestamp(long creationTimestamp) + { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public DetachedThreadChannelImpl setOwnerId(long ownerId) + { + this.ownerId = ownerId; + return this; + } + + @Override + public DetachedThreadChannelImpl setMessageCount(int messageCount) + { + this.messageCount = messageCount; + return this; + } + + @Override + public DetachedThreadChannelImpl setTotalMessageCount(int messageCount) + { + this.totalMessageCount = Math.max(messageCount, this.messageCount); // If this is 0 we use the older count + return this; + } + + @Override + public DetachedThreadChannelImpl setMemberCount(int memberCount) + { + this.memberCount = memberCount; + return this; + } + + @Override + public DetachedThreadChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Override + public DetachedThreadChannelImpl setFlags(int flags) + { + this.flags = flags; + return this; + } + + @Nonnull + @Override + public DetachedThreadChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedVoiceChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedVoiceChannelImpl.java new file mode 100644 index 0000000000..fbadb68108 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedVoiceChannelImpl.java @@ -0,0 +1,203 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.concrete.detached; + +import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.managers.channel.concrete.VoiceChannelManager; +import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; +import net.dv8tion.jda.internal.entities.channel.middleman.AbstractStandardGuildChannelImpl; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IInteractionPermissionMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.concrete.VoiceChannelMixin; +import net.dv8tion.jda.internal.entities.detached.DetachedGuildImpl; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class DetachedVoiceChannelImpl extends AbstractStandardGuildChannelImpl + implements + VoiceChannel, + VoiceChannelMixin, + IInteractionPermissionMixin +{ + private ChannelInteractionPermissions interactionPermissions; + + private String region; + private String status = ""; + private long latestMessageId; + private int bitrate; + private int userLimit; + private int slowmode; + private boolean nsfw; + + public DetachedVoiceChannelImpl(long id, DetachedGuildImpl guild) + { + super(id, guild); + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public ChannelType getType() + { + return ChannelType.VOICE; + } + + @Override + public int getBitrate() + { + return bitrate; + } + + @Nullable + @Override + public String getRegionRaw() + { + return region; + } + + @Override + public int getUserLimit() + { + return userLimit; + } + + @Override + public boolean isNSFW() + { + return nsfw; + } + + @Override + public int getSlowmode() + { + return slowmode; + } + + @Override + public long getLatestMessageIdLong() + { + return latestMessageId; + } + + @Nonnull + @Override + public List getMembers() + { + throw detachedException(); + } + + @Nonnull + @Override + public VoiceChannelManager getManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public String getStatus() + { + return status; + } + + @Nonnull + @Override + public AuditableRestAction modifyStatus(@Nonnull String status) + { + throw detachedException(); + } + + @Override + public TLongObjectMap getConnectedMembersMap() + { + throw detachedException(); + } + + @Nonnull + @Override + public ChannelInteractionPermissions getInteractionPermissions() + { + return interactionPermissions; + } + + @Override + public DetachedVoiceChannelImpl setBitrate(int bitrate) + { + this.bitrate = bitrate; + return this; + } + + @Override + public DetachedVoiceChannelImpl setRegion(String region) + { + this.region = region; + return this; + } + + @Override + public DetachedVoiceChannelImpl setUserLimit(int userLimit) + { + this.userLimit = userLimit; + return this; + } + + @Override + public DetachedVoiceChannelImpl setNSFW(boolean nsfw) + { + this.nsfw = nsfw; + return this; + } + + @Override + public DetachedVoiceChannelImpl setSlowmode(int slowmode) + { + this.slowmode = slowmode; + return this; + } + + @Override + public DetachedVoiceChannelImpl setLatestMessageIdLong(long latestMessageId) + { + this.latestMessageId = latestMessageId; + return this; + } + + @Override + public DetachedVoiceChannelImpl setStatus(String status) + { + this.status = status; + return this; + } + + @Nonnull + @Override + public DetachedVoiceChannelImpl setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions) + { + this.interactionPermissions = interactionPermissions; + return this; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractGuildChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractGuildChannelImpl.java index b8b648d9fa..9397b6c754 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractGuildChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractGuildChannelImpl.java @@ -16,8 +16,8 @@ package net.dv8tion.jda.internal.entities.channel.middleman; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; -import net.dv8tion.jda.internal.entities.GuildImpl; import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl; import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildChannelMixin; import net.dv8tion.jda.internal.utils.ChannelUtil; @@ -26,9 +26,9 @@ public abstract class AbstractGuildChannelImpl> extends AbstractChannelImpl implements GuildChannelMixin { - protected GuildImpl guild; + protected Guild guild; - public AbstractGuildChannelImpl(long id, GuildImpl guild) + public AbstractGuildChannelImpl(long id, Guild guild) { super(id, guild.getJDA()); this.guild = guild; @@ -36,7 +36,7 @@ public AbstractGuildChannelImpl(long id, GuildImpl guild) @Nonnull @Override - public GuildImpl getGuild() + public Guild getGuild() { return guild; } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractStandardGuildChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractStandardGuildChannelImpl.java index 3f28c46714..2b51adce8e 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractStandardGuildChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/middleman/AbstractStandardGuildChannelImpl.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.internal.entities.channel.middleman; import gnu.trove.map.TLongObjectMap; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.PermissionOverride; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.internal.entities.GuildImpl; @@ -30,7 +31,7 @@ public abstract class AbstractStandardGuildChannelImpl> extends Channel, - ChannelUnion + ChannelUnion, + IDetachableEntityMixin { // ---- Default implementations of interface ---- @Override @@ -35,11 +37,11 @@ public interface ChannelMixin> extends @CheckReturnValue default RestAction delete() { + checkCanAccess(); Route.CompiledRoute route = Route.Channels.DELETE_CHANNEL.compile(getId()); return new RestActionImpl<>(getJDA(), route); } - // ---- State Accessors ---- T setName(String name); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInteractionPermissionMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInteractionPermissionMixin.java new file mode 100644 index 0000000000..12f9a46ee8 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInteractionPermissionMixin.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.attribute; + +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildChannelMixin; +import net.dv8tion.jda.internal.interactions.ChannelInteractionPermissions; + +import javax.annotation.Nonnull; + +public interface IInteractionPermissionMixin> extends + GuildChannelMixin +{ + @Nonnull + ChannelInteractionPermissions getInteractionPermissions(); + + @Nonnull + T setInteractionPermissions(@Nonnull ChannelInteractionPermissions interactionPermissions); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInviteContainerMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInviteContainerMixin.java index 55ead6fdd5..49ff5becc0 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInviteContainerMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IInviteContainerMixin.java @@ -41,6 +41,7 @@ public interface IInviteContainerMixin> exten @Override default InviteAction createInvite() { + checkAttached(); checkPermission(Permission.CREATE_INSTANT_INVITE); return new InviteActionImpl(this.getJDA(), this.getId()); @@ -50,6 +51,7 @@ default InviteAction createInvite() @Override default RestAction> retrieveInvites() { + checkAttached(); checkPermission(Permission.MANAGE_CHANNEL); final Route.CompiledRoute route = Route.Invites.GET_CHANNEL_INVITES.compile(getId()); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPermissionContainerMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPermissionContainerMixin.java index 6c6dfac527..c6573ba9e5 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPermissionContainerMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPermissionContainerMixin.java @@ -59,6 +59,7 @@ default List getPermissionOverrides() @Override default PermissionOverrideAction upsertPermissionOverride(@Nonnull IPermissionHolder permissionHolder) { + checkAttached(); checkPermission(Permission.MANAGE_PERMISSIONS); Checks.notNull(permissionHolder, "PermissionHolder"); Checks.check(permissionHolder.getGuild().equals(getGuild()), "Provided permission holder is not from the same guild as this channel!"); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPostContainerMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPostContainerMixin.java index 114e1e770e..c2109ee65f 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPostContainerMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IPostContainerMixin.java @@ -39,6 +39,7 @@ public interface IPostContainerMixin> extends I @Override default ForumPostAction createForumPost(@Nonnull String name, @Nonnull MessageCreateData message) { + checkAttached(); checkPermission(Permission.MESSAGE_SEND); return new ForumPostActionImpl(this, name, new MessageCreateBuilder().applyData(message)); } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IThreadContainerMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IThreadContainerMixin.java index 82924e6308..8d12c21e0d 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IThreadContainerMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IThreadContainerMixin.java @@ -45,6 +45,7 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, boolean is Checks.notEmpty(name, "Name"); Checks.notLonger(name, 100, "Name"); + checkAttached(); Checks.checkAccess(getGuild().getSelfMember(), this); if (isPrivate) checkPermission(Permission.CREATE_PRIVATE_THREADS); @@ -69,6 +70,7 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, long messa Checks.notEmpty(name, "Name"); Checks.notLonger(name, 100, "Name"); + checkAttached(); Checks.checkAccess(getGuild().getSelfMember(), this); checkPermission(Permission.CREATE_PUBLIC_THREADS); @@ -79,6 +81,7 @@ default ThreadChannelAction createThreadChannel(@Nonnull String name, long messa @Override default ThreadChannelPaginationAction retrieveArchivedPublicThreadChannels() { + checkAttached(); Checks.checkAccess(getGuild().getSelfMember(), this); checkPermission(Permission.MESSAGE_HISTORY); @@ -90,6 +93,7 @@ default ThreadChannelPaginationAction retrieveArchivedPublicThreadChannels() @Override default ThreadChannelPaginationAction retrieveArchivedPrivateThreadChannels() { + checkAttached(); Checks.checkAccess(getGuild().getSelfMember(), this); checkPermission(Permission.MESSAGE_HISTORY); checkPermission(Permission.MANAGE_THREADS); @@ -102,6 +106,7 @@ default ThreadChannelPaginationAction retrieveArchivedPrivateThreadChannels() @Override default ThreadChannelPaginationAction retrieveArchivedPrivateJoinedThreadChannels() { + checkAttached(); Checks.checkAccess(getGuild().getSelfMember(), this); checkPermission(Permission.MESSAGE_HISTORY); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IWebhookContainerMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IWebhookContainerMixin.java index 55b30d08fe..a614ccb019 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IWebhookContainerMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/attribute/IWebhookContainerMixin.java @@ -49,6 +49,7 @@ public interface IWebhookContainerMixin> ext @Override default RestAction> retrieveWebhooks() { + checkAttached(); checkPermission(Permission.MANAGE_WEBHOOKS); Route.CompiledRoute route = Route.Channels.GET_WEBHOOKS.compile(getId()); @@ -84,6 +85,7 @@ default WebhookAction createWebhook(@Nonnull String name) Checks.notEmpty(name, "Name"); Checks.notLonger(name, 100, "Name"); + checkAttached(); checkPermission(Permission.MANAGE_WEBHOOKS); return new WebhookActionImpl(getJDA(), this, name); @@ -95,6 +97,7 @@ default AuditableRestAction deleteWebhookById(@Nonnull String id) { Checks.isSnowflake(id, "Webhook ID"); + checkAttached(); checkPermission(Permission.MANAGE_WEBHOOKS); Route.CompiledRoute route = Route.Webhooks.DELETE_WEBHOOK.compile(id); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/CategoryMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/CategoryMixin.java new file mode 100644 index 0000000000..ce0ffa1bae --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/CategoryMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPermissionContainerMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IPositionableChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface CategoryMixin> + extends Category, + IPositionableChannelMixin, + IPermissionContainerMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + ChannelAction action = guild.createCategory(getName()); + if (guild.equals(getGuild())) + { + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ForumChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ForumChannelMixin.java new file mode 100644 index 0000000000..e8a0daf55c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ForumChannelMixin.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel; +import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.*; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface ForumChannelMixin> + extends ForumChannel, + StandardGuildChannelMixin, + IAgeRestrictedChannelMixin, + ISlowmodeChannelMixin, + IWebhookContainerMixin, + IPostContainerMixin, + ITopicChannelMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + ChannelAction action = guild.createForumChannel(getName()) + .setNSFW(isNSFW()) + .setTopic(getTopic()) + .setSlowmode(getSlowmode()) + .setAvailableTags(getAvailableTags()) + .setDefaultLayout(getDefaultLayout()); + if (getRawSortOrder() != -1) + action.setDefaultSortOrder(SortOrder.fromKey(getRawSortOrder())); + if (getDefaultReaction() instanceof UnicodeEmoji) + action.setDefaultReaction(getDefaultReaction()); + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + action.setDefaultReaction(getDefaultReaction()); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } + + T setDefaultLayout(int layout); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/GroupChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/GroupChannelMixin.java new file mode 100644 index 0000000000..11fea0b867 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/GroupChannelMixin.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.channel.concrete.GroupChannel; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.MessageChannelMixin; + +import javax.annotation.Nullable; + +public interface GroupChannelMixin> + extends GroupChannel, + MessageChannelMixin +{ + T setOwnerId(long ownerId); + + T setIcon(@Nullable String icon); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/MediaChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/MediaChannelMixin.java new file mode 100644 index 0000000000..273b11fbe9 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/MediaChannelMixin.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.MediaChannel; +import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.*; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface MediaChannelMixin> + extends MediaChannel, + StandardGuildChannelMixin, + IAgeRestrictedChannelMixin, + ISlowmodeChannelMixin, + IWebhookContainerMixin, + IPostContainerMixin, + ITopicChannelMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + ChannelAction action = guild.createMediaChannel(getName()) + .setNSFW(isNSFW()) + .setTopic(getTopic()) + .setSlowmode(getSlowmode()) + .setAvailableTags(getAvailableTags()); + if (getRawSortOrder() != -1) + action.setDefaultSortOrder(SortOrder.fromKey(getRawSortOrder())); + if (getDefaultReaction() instanceof UnicodeEmoji) + action.setDefaultReaction(getDefaultReaction()); + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + action.setDefaultReaction(getDefaultReaction()); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/NewsChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/NewsChannelMixin.java new file mode 100644 index 0000000000..12ca03f847 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/NewsChannelMixin.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildMessageChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface NewsChannelMixin> + extends NewsChannel, + StandardGuildMessageChannelMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + ChannelAction action = guild.createNewsChannel(getName()).setNSFW(isNSFW()).setTopic(getTopic()); + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/PrivateChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/PrivateChannelMixin.java new file mode 100644 index 0000000000..861fc2a88f --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/PrivateChannelMixin.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.MessageChannelMixin; + +public interface PrivateChannelMixin> + extends PrivateChannel, + MessageChannelMixin +{ + +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/StageChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/StageChannelMixin.java new file mode 100644 index 0000000000..dc9710c497 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/StageChannelMixin.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.Region; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.StageChannel; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IAgeRestrictedChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IWebhookContainerMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.AudioChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface StageChannelMixin> + extends StageChannel, + AudioChannelMixin, + GuildMessageChannelMixin, + IWebhookContainerMixin, + IAgeRestrictedChannelMixin, + ISlowmodeChannelMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + + ChannelAction action = guild.createStageChannel(getName()).setBitrate(getBitrate()); + + if (getRegionRaw() != null) + { + action.setRegion(Region.fromKey(getRegionRaw())); + } + + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/TextChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/TextChannelMixin.java new file mode 100644 index 0000000000..3a70fe970c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/TextChannelMixin.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.StandardGuildMessageChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface TextChannelMixin> + extends TextChannel, + StandardGuildMessageChannelMixin, + ISlowmodeChannelMixin +{ + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + ChannelAction action = guild.createTextChannel(getName()).setNSFW(isNSFW()).setTopic(getTopic()).setSlowmode(getSlowmode()); + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ThreadChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ThreadChannelMixin.java new file mode 100644 index 0000000000..321772754d --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/ThreadChannelMixin.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; + +public interface ThreadChannelMixin> + extends ThreadChannel, + GuildMessageChannelMixin, + ISlowmodeChannelMixin +{ + T setAutoArchiveDuration(AutoArchiveDuration autoArchiveDuration); + + T setLocked(boolean locked); + + T setArchived(boolean archived); + + T setInvitable(boolean invitable); + + T setArchiveTimestamp(long archiveTimestamp); + + T setCreationTimestamp(long creationTimestamp); + + T setOwnerId(long ownerId); + + T setMessageCount(int messageCount); + + T setTotalMessageCount(int messageCount); + + T setMemberCount(int memberCount); + + T setFlags(int flags); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/VoiceChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/VoiceChannelMixin.java new file mode 100644 index 0000000000..9d1c18a123 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/concrete/VoiceChannelMixin.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.channel.mixin.concrete; + +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.Region; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.PermissionOverride; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.requests.restaction.ChannelAction; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IAgeRestrictedChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.ISlowmodeChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.attribute.IWebhookContainerMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.AudioChannelMixin; +import net.dv8tion.jda.internal.entities.channel.mixin.middleman.GuildMessageChannelMixin; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public interface VoiceChannelMixin> + extends VoiceChannel, + GuildMessageChannelMixin, + AudioChannelMixin, + IWebhookContainerMixin, + IAgeRestrictedChannelMixin, + ISlowmodeChannelMixin +{ + @Override + default boolean canTalk(@Nonnull Member member) + { + Checks.notNull(member, "Member"); + return member.hasPermission(this, Permission.MESSAGE_SEND); + } + + @Nonnull + @Override + default ChannelAction createCopy(@Nonnull Guild guild) + { + Checks.notNull(guild, "Guild"); + + ChannelAction action = guild.createVoiceChannel(getName()) + .setBitrate(getBitrate()) + .setUserlimit(getUserLimit()); + + if (getRegionRaw() != null) + action.setRegion(Region.fromKey(getRegionRaw())); + + if (guild.equals(getGuild())) + { + Category parent = getParentCategory(); + if (parent != null) + action.setParent(parent); + for (PermissionOverride o : getPermissionOverrideMap().valueCollection()) + { + if (o.isMemberOverride()) + action.addMemberPermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + else + action.addRolePermissionOverride(o.getIdLong(), o.getAllowedRaw(), o.getDeniedRaw()); + } + } + return action; + } + + T setStatus(String status); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/AudioChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/AudioChannelMixin.java index 60b1e02b2e..5f1f94c18a 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/AudioChannelMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/AudioChannelMixin.java @@ -38,6 +38,7 @@ public interface AudioChannelMixin> @Override default void checkCanAccess() { + checkAttached(); if (!hasPermission(Permission.VIEW_CHANNEL)) throw new MissingAccessException(this, Permission.VIEW_CHANNEL); if (!hasPermission(Permission.VOICE_CONNECT)) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/GuildChannelMixin.java b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/GuildChannelMixin.java index bd2825a1bb..49caeb1707 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/GuildChannelMixin.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/channel/mixin/middleman/GuildChannelMixin.java @@ -25,6 +25,7 @@ import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; import net.dv8tion.jda.internal.entities.channel.mixin.ChannelMixin; +import net.dv8tion.jda.internal.entities.detached.mixin.IDetachableEntityMixin; import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl; import javax.annotation.CheckReturnValue; @@ -33,7 +34,8 @@ public interface GuildChannelMixin> extends GuildChannel, GuildChannelUnion, - ChannelMixin + ChannelMixin, + IDetachableEntityMixin { // ---- Default implementations of interface ---- @Override @@ -76,6 +78,7 @@ default void checkCanManage() // Overridden by AudioChannelMixin default void checkCanAccess() { + checkAttached(); if (!hasPermission(Permission.VIEW_CHANNEL)) throw new MissingAccessException(this, Permission.VIEW_CHANNEL); } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/detached/DetachedGuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/detached/DetachedGuildImpl.java new file mode 100644 index 0000000000..7dbe4dcca2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/detached/DetachedGuildImpl.java @@ -0,0 +1,1074 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.detached; + +import net.dv8tion.jda.api.Region; +import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.*; +import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion; +import net.dv8tion.jda.api.entities.emoji.CustomEmoji; +import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; +import net.dv8tion.jda.api.entities.sticker.GuildSticker; +import net.dv8tion.jda.api.entities.sticker.StickerSnowflake; +import net.dv8tion.jda.api.entities.templates.Template; +import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.commands.Command; +import net.dv8tion.jda.api.interactions.commands.PrivilegeConfig; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege; +import net.dv8tion.jda.api.managers.*; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.requests.restaction.*; +import net.dv8tion.jda.api.requests.restaction.order.CategoryOrderAction; +import net.dv8tion.jda.api.requests.restaction.order.ChannelOrderAction; +import net.dv8tion.jda.api.requests.restaction.order.RoleOrderAction; +import net.dv8tion.jda.api.requests.restaction.pagination.AuditLogPaginationAction; +import net.dv8tion.jda.api.utils.FileUpload; +import net.dv8tion.jda.api.utils.cache.MemberCacheView; +import net.dv8tion.jda.api.utils.cache.SnowflakeCacheView; +import net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView; +import net.dv8tion.jda.api.utils.concurrent.Task; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.detached.mixin.IDetachableEntityMixin; +import net.dv8tion.jda.internal.requests.restaction.pagination.BanPaginationActionImpl; +import net.dv8tion.jda.internal.utils.EntityString; +import net.dv8tion.jda.internal.utils.cache.SortedChannelCacheViewImpl; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.time.temporal.TemporalAccessor; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class DetachedGuildImpl implements Guild, IDetachableEntityMixin +{ + private final long id; + private final JDAImpl api; + + private Set features; + private DiscordLocale preferredLocale = DiscordLocale.ENGLISH_US; + + public DetachedGuildImpl(JDAImpl api, long id) + { + this.id = id; + this.api = api; + } + + @Override + public boolean isDetached() + { + return true; + } + + @Nonnull + @Override + public RestAction> retrieveCommands(boolean withLocalizations) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveCommandById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public CommandCreateAction upsertCommand(@Nonnull CommandData command) + { + throw detachedException(); + } + + @Nonnull + @Override + public CommandListUpdateAction updateCommands() + { + throw detachedException(); + } + + @Nonnull + @Override + public CommandEditAction editCommandById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction deleteCommandById(@Nonnull String commandId) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveIntegrationPrivilegesById(@Nonnull String targetId) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveCommandPrivileges() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveRegions(boolean includeDeprecated) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveAutoModRules() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveAutoModRuleById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData rule) + { + throw detachedException(); + } + + @Nonnull + @Override + public AutoModRuleManager modifyAutoModRuleById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public AuditableRestAction deleteAutoModRuleById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public MemberAction addMember(@Nonnull String accessToken, @Nonnull UserSnowflake user) + { + throw detachedException(); + } + + @Override + public boolean isLoaded() + { + throw detachedException(); + } + + @Override + public void pruneMemberCache() + { + throw detachedException(); + } + + @Override + public boolean unloadMember(long userId) + { + throw detachedException(); + } + + @Override + public int getMemberCount() + { + throw detachedException(); + } + + @Nonnull + @Override + public String getName() + { + throw detachedException(); + } + + @Override + public String getIconId() + { + throw detachedException(); + } + + @Nonnull + @Override + public Set getFeatures() + { + return features; + } + + @Override + public String getSplashId() + { + throw detachedException(); + } + + @Nullable + @Override + public String getVanityCode() + { + throw detachedException(); + } + + @Override + @Nonnull + public RestAction retrieveVanityInvite() + { + throw detachedException(); + } + + @Nullable + @Override + public String getDescription() + { + throw detachedException(); + } + + @Nonnull + @Override + public DiscordLocale getLocale() + { + return preferredLocale; + } + + @Nullable + @Override + public String getBannerId() + { + throw detachedException(); + } + + @Nonnull + @Override + public BoostTier getBoostTier() + { + throw detachedException(); + } + + @Override + public int getBoostCount() + { + throw detachedException(); + } + + @Nonnull + @Override + @SuppressWarnings("ConstantConditions") // can't be null here + public List getBoosters() + { + throw detachedException(); + } + + @Override + public int getMaxMembers() + { + throw detachedException(); + } + + @Override + public int getMaxPresences() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveMetaData() + { + throw detachedException(); + } + + @Override + public VoiceChannel getAfkChannel() + { + throw detachedException(); + } + + @Override + public TextChannel getSystemChannel() + { + throw detachedException(); + } + + @Override + public TextChannel getRulesChannel() + { + throw detachedException(); + } + + @Nonnull + @Override + public CacheRestAction retrieveScheduledEventById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public CacheRestAction retrieveScheduledEventById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public ScheduledEventAction createScheduledEvent(@Nonnull String name, @Nonnull String location, @Nonnull OffsetDateTime startTime, @Nonnull OffsetDateTime endTime) + { + throw detachedException(); + } + + @Nonnull + @Override + public ScheduledEventAction createScheduledEvent(@Nonnull String name, @Nonnull GuildChannel channel, @Nonnull OffsetDateTime startTime) + { + throw detachedException(); + } + + + @Override + public TextChannel getCommunityUpdatesChannel() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveWebhooks() + { + throw detachedException(); + } + + @Override + public Member getOwner() + { + throw detachedException(); + } + + @Override + public long getOwnerIdLong() + { + throw detachedException(); + } + + @Nonnull + @Override + public Timeout getAfkTimeout() + { + throw detachedException(); + } + + @Override + public boolean isMember(@Nonnull UserSnowflake user) + { + throw detachedException(); + } + + @Nonnull + @Override + public Member getSelfMember() + { + throw detachedException(); + } + + @Override + public Member getMember(@Nonnull UserSnowflake user) + { + throw detachedException(); + } + + @Nonnull + @Override + public Task> findMembers(@Nonnull Predicate filter) + { + throw detachedException(); + } + + @Nonnull + @Override + public MemberCacheView getMemberCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getScheduledEventCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getCategoryCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getTextChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getNewsChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getVoiceChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getForumChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SnowflakeCacheView getMediaChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getStageChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getThreadChannelCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedChannelCacheViewImpl getChannelCache() + { + throw detachedException(); + } + + @Nullable + @Override + public GuildChannel getGuildChannelById(long id) + { + throw detachedException(); + } + + @Override + public GuildChannel getGuildChannelById(@Nonnull ChannelType type, long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public SortedSnowflakeCacheView getRoleCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SnowflakeCacheView getEmojiCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public SnowflakeCacheView getStickerCache() + { + throw detachedException(); + } + + @Nonnull + @Override + public List getChannels(boolean includeHidden) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveEmojis() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveEmojiById(@Nonnull String id) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveEmoji(@Nonnull CustomEmoji emoji) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveStickers() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveSticker(@Nonnull StickerSnowflake sticker) + { + throw detachedException(); + } + + @Nonnull + @Override + public GuildStickerManager editSticker(@Nonnull StickerSnowflake sticker) + { + throw detachedException(); + } + + @Nonnull + @Override + public BanPaginationActionImpl retrieveBanList() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrieveBan(@Nonnull UserSnowflake user) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction retrievePrunableMemberCount(int days) + { + throw detachedException(); + } + + @Nonnull + @Override + public Role getPublicRole() + { + throw detachedException(); + } + + @Nullable + @Override + public DefaultGuildChannelUnion getDefaultChannel() + { + throw detachedException(); + } + + @Nonnull + @Override + public GuildManager getManager() + { + throw detachedException(); + } + + @Override + public boolean isBoostProgressBarEnabled() + { + throw detachedException(); + } + + @Nonnull + @Override + public AuditLogPaginationAction retrieveAuditLogs() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction leave() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction delete() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction delete(String mfaCode) + { + throw detachedException(); + } + + @Nonnull + @Override + public AudioManager getAudioManager() + { + throw detachedException(); + } + + @Nonnull + @Override + public synchronized Task requestToSpeak() + { + throw detachedException(); + } + + @Nonnull + @Override + public synchronized Task cancelRequestToSpeak() + { + throw detachedException(); + } + + @Nonnull + @Override + public JDAImpl getJDA() + { + return api; + } + + @Nonnull + @Override + public List getVoiceStates() + { + throw detachedException(); + } + + @Nonnull + @Override + public VerificationLevel getVerificationLevel() + { + throw detachedException(); + } + + @Nonnull + @Override + public NSFWLevel getNSFWLevel() + { + throw detachedException(); + } + + @Nonnull + @Override + public NotificationLevel getDefaultNotificationLevel() + { + throw detachedException(); + } + + @Nonnull + @Override + public MFALevel getRequiredMFALevel() + { + throw detachedException(); + } + + @Nonnull + @Override + public ExplicitContentLevel getExplicitContentLevel() + { + throw detachedException(); + } + + @Nonnull + @Override + public Task loadMembers(@Nonnull Consumer callback) + { + throw detachedException(); + } + + @Nonnull + @Override + public CacheRestAction retrieveMemberById(long id) + { + throw detachedException(); + } + + @Nonnull + @Override + public Task> retrieveMembersByIds(boolean includePresence, @Nonnull long... ids) + { + throw detachedException(); + } + + @Nonnull + @Override + @CheckReturnValue + public Task> retrieveMembersByPrefix(@Nonnull String prefix, int limit) + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveActiveThreads() + { + throw detachedException(); + } + + @Override + public long getIdLong() + { + return id; + } + + @Nonnull + @Override + public RestAction> retrieveInvites() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction> retrieveTemplates() + { + throw detachedException(); + } + + @Nonnull + @Override + public RestAction