From 3e37938a3ac080bab94e9525cfee5e10c4647523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Tue, 15 Nov 2022 11:49:33 +0100 Subject: [PATCH] Add support for age-restricted (nsfw) commands (#2325) --- .../api/interactions/commands/Command.java | 9 +++++++ .../commands/build/CommandData.java | 27 +++++++++++++++++++ .../commands/build/SlashCommandData.java | 6 +++++ .../restaction/CommandCreateAction.java | 4 +++ .../restaction/CommandEditAction.java | 17 ++++++++++++ .../interactions/CommandDataImpl.java | 16 +++++++++++ .../interactions/command/CommandImpl.java | 9 ++++++- .../restaction/CommandCreateActionImpl.java | 14 ++++++++++ .../restaction/CommandEditActionImpl.java | 22 ++++++++++++++- 9 files changed, 122 insertions(+), 2 deletions(-) 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 530793385d..8f2b1e8157 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 @@ -228,6 +228,15 @@ default OffsetDateTime getTimeModified() */ boolean isGuildOnly(); + /** + * Whether this command is restricted to NSFW (age-restricted) channels. + * + * @return True, if this command is NSFW + * + * @see Age-Restricted Commands FAQ + */ + boolean isNSFW(); + /** * Possible command types */ 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 9ee84f2d92..29b8e4910a 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 @@ -146,6 +146,22 @@ public interface CommandData extends SerializableData @Nonnull CommandData setGuildOnly(boolean guildOnly); + /** + * Sets whether this command should only be usable in NSFW (age-restricted) channels. + *
Default: false + * + *

Note: Age-restricted commands will not show up in direct messages by default unless the user enables them in their settings. + * + * @param nsfw + * True, to make this command nsfw + * + * @return The builder instance, for chaining + * + * @see Age-Restricted Commands FAQ + */ + @Nonnull + CommandData setNSFW(boolean nsfw); + /** * The current command name * @@ -190,6 +206,15 @@ public interface CommandData extends SerializableData */ boolean isGuildOnly(); + /** + * Whether this command should only be usable in NSFW (age-restricted) channels + * + * @return True, if this command is restricted to NSFW channels + * + * @see Age-Restricted Commands FAQ + */ + boolean isNSFW(); + /** * Converts the provided {@link Command} into a CommandData instance. * @@ -212,6 +237,7 @@ static CommandData fromCommand(@Nonnull Command command) final CommandDataImpl data = new CommandDataImpl(command.getType(), command.getName()); return data.setDefaultPermissions(command.getDefaultPermissions()) .setGuildOnly(command.isGuildOnly()) + .setNSFW(command.isNSFW()) .setNameLocalizations(command.getNameLocalizations().toMap()) .setDescriptionLocalizations(command.getDescriptionLocalizations().toMap()); } @@ -252,6 +278,7 @@ static CommandData fromData(@Nonnull DataObject object) } data.setGuildOnly(!object.getBoolean("dm_permission", true)); + data.setNSFW(object.getBoolean("nsfw")); data.setNameLocalizations(LocalizationUtils.mapFromProperty(object, "name_localizations")); data.setDescriptionLocalizations(LocalizationUtils.mapFromProperty(object, "description_localizations")); return data; 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 7c1d0bbee4..700283dbe4 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 @@ -63,6 +63,10 @@ public interface SlashCommandData extends CommandData @Override SlashCommandData setGuildOnly(boolean guildOnly); + @Nonnull + @Override + SlashCommandData setNSFW(boolean nsfw); + /** * Configure the description * @@ -405,6 +409,7 @@ static SlashCommandData fromCommand(@Nonnull Command command) CommandDataImpl data = new CommandDataImpl(command.getName(), command.getDescription()); data.setGuildOnly(command.isGuildOnly()); + data.setNSFW(command.isNSFW()); data.setDefaultPermissions(command.getDefaultPermissions()); //Command localizations are unmodifiable, make a copy data.setNameLocalizations(command.getNameLocalizations().toMap()); @@ -454,6 +459,7 @@ static SlashCommandData fromData(@Nonnull DataObject object) DataArray options = object.optArray("options").orElseGet(DataArray::empty); CommandDataImpl command = new CommandDataImpl(name, description); command.setGuildOnly(!object.getBoolean("dm_permission", true)); + command.setNSFW(object.getBoolean("nsfw")); command.setDefaultPermissions( object.isNull("default_member_permissions") 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 683d88569d..a55b648810 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 @@ -168,4 +168,8 @@ default CommandCreateAction addSubcommandGroups(@Nonnull Collection @CheckReturnValue CommandEditAction setGuildOnly(boolean guildOnly); + /** + * Sets whether this command should only be usable in NSFW (age-restricted) channels. + *
Default: false + * + *

Note: Age-restricted commands will not show up in direct messages by default unless the user enables them in their settings. + * + * @param nsfw + * True, to make this command nsfw + * + * @return The CommandEditAction instance, for chaining + * + * @see Age-Restricted Commands FAQ + */ + @Nonnull + @CheckReturnValue + CommandEditAction setNSFW(boolean nsfw); + /** * Sets the {@link net.dv8tion.jda.api.Permission Permissions} that a user must have in a specific channel to be able to use this command. *
By default, everyone can use this command ({@link DefaultMemberPermissions#ENABLED}). Additionally, a command can be disabled for everyone but admins via {@link DefaultMemberPermissions#DISABLED}. diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/CommandDataImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/CommandDataImpl.java index 1b03d07fb0..1538f07e54 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/CommandDataImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/CommandDataImpl.java @@ -51,6 +51,7 @@ public class CommandDataImpl implements SlashCommandData private boolean allowOption = true; private boolean allowRequired = true; private boolean guildOnly = false; + private boolean nsfw = false; private DefaultMemberPermissions defaultMemberPermissions = DefaultMemberPermissions.ENABLED; private final Command.Type type; @@ -102,6 +103,7 @@ public DataObject toData() DataObject json = DataObject.empty() .put("type", type.getId()) .put("name", name) + .put("nsfw", nsfw) .put("options", options) .put("dm_permission", !guildOnly) .put("default_member_permissions", defaultMemberPermissions == DefaultMemberPermissions.ENABLED @@ -135,6 +137,12 @@ public boolean isGuildOnly() return guildOnly; } + @Override + public boolean isNSFW() + { + return nsfw; + } + @Nonnull @Override public List getSubcommands() @@ -180,6 +188,14 @@ public CommandDataImpl setGuildOnly(boolean guildOnly) return this; } + @Nonnull + @Override + public CommandDataImpl setNSFW(boolean nsfw) + { + this.nsfw = nsfw; + return this; + } + @Nonnull @Override public CommandDataImpl addOptions(@Nonnull OptionData... options) diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandImpl.java index dcbba66ef5..0de2302905 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandImpl.java @@ -59,7 +59,7 @@ public class CommandImpl implements Command private final List groups; private final List subcommands; private final long id, guildId, applicationId, version; - private final boolean guildOnly; + private final boolean guildOnly, nsfw; private final Command.Type type; private final DefaultMemberPermissions defaultMemberPermissions; @@ -85,6 +85,7 @@ public CommandImpl(JDAImpl api, Guild guild, DataObject json) : DefaultMemberPermissions.enabledFor(json.getLong("default_member_permissions")); this.guildOnly = !json.getBoolean("dm_permission", true); + this.nsfw = json.getBoolean("nsfw"); } public static List parseOptions(DataObject json, Predicate test, Function transform) @@ -223,6 +224,12 @@ public boolean isGuildOnly() return guildOnly; } + @Override + public boolean isNSFW() + { + return nsfw; + } + @Override public long getIdLong() { diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java index 1593c6f687..2cde3a4ad8 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java @@ -97,6 +97,14 @@ public CommandCreateAction setGuildOnly(boolean guildOnly) return this; } + @Nonnull + @Override + public CommandCreateAction setNSFW(boolean nsfw) + { + data.setNSFW(nsfw); + return this; + } + @Nonnull @Override public CommandCreateAction setLocalizationFunction(@Nonnull LocalizationFunction localizationFunction) @@ -139,6 +147,12 @@ public boolean isGuildOnly() return data.isGuildOnly(); } + @Override + public boolean isNSFW() + { + return data.isNSFW(); + } + @Nonnull @Override public CommandCreateAction timeout(long timeout, @Nonnull TimeUnit unit) diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandEditActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandEditActionImpl.java index b01fff31bd..01cbc8148f 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandEditActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandEditActionImpl.java @@ -46,6 +46,9 @@ public class CommandEditActionImpl extends RestActionImpl implements Co private static final int NAME_SET = 1 << 0; private static final int DESCRIPTION_SET = 1 << 1; private static final int OPTIONS_SET = 1 << 2; + private static final int PERMISSIONS_SET = 1 << 3; + private static final int GUILD_ONLY_SET = 1 << 4; + private static final int NSFW_SET = 1 << 5; private final Guild guild; private int mask = 0; private CommandDataImpl data = new CommandDataImpl(UNDEFINED, UNDEFINED); @@ -81,7 +84,7 @@ public CommandEditAction deadline(long timestamp) public CommandEditAction apply(@Nonnull CommandData commandData) { Checks.notNull(commandData, "Command Data"); - this.mask = NAME_SET | DESCRIPTION_SET | OPTIONS_SET; + this.mask = NAME_SET | DESCRIPTION_SET | OPTIONS_SET | PERMISSIONS_SET | GUILD_ONLY_SET | NSFW_SET; this.data = (CommandDataImpl) commandData; return this; } @@ -119,6 +122,16 @@ public CommandEditAction setName(@Nullable String name) public CommandEditAction setGuildOnly(boolean guildOnly) { data.setGuildOnly(guildOnly); + mask |= GUILD_ONLY_SET; + return this; + } + + @Nonnull + @Override + public CommandEditAction setNSFW(boolean nsfw) + { + data.setNSFW(nsfw); + mask |= NSFW_SET; return this; } @@ -127,6 +140,7 @@ public CommandEditAction setGuildOnly(boolean guildOnly) public CommandEditAction setDefaultPermissions(@Nonnull DefaultMemberPermissions permission) { data.setDefaultPermissions(permission); + mask |= PERMISSIONS_SET; return this; } @@ -195,6 +209,12 @@ protected RequestBody finalizeData() json.remove("description"); if (isUnchanged(OPTIONS_SET)) json.remove("options"); + if (isUnchanged(PERMISSIONS_SET)) + json.remove("default_member_permissions"); + if (isUnchanged(GUILD_ONLY_SET)) + json.remove("dm_permission"); + if (isUnchanged(NSFW_SET)) + json.remove("nsfw"); mask = 0; data = new CommandDataImpl(UNDEFINED, UNDEFINED); return getRequestBody(json);