Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for age-restricted (nsfw) commands #2325

Merged
merged 2 commits into from Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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 <a href="https://support.discord.com/hc/en-us/articles/10123937946007" target="_blank">Age-Restricted Commands FAQ</a>
*/
boolean isNSFW();

/**
* Possible command types
*/
Expand Down
Expand Up @@ -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.
* <br>Default: false
*
* <p>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 <a href="https://support.discord.com/hc/en-us/articles/10123937946007" target="_blank">Age-Restricted Commands FAQ</a>
*/
@Nonnull
CommandData setNSFW(boolean nsfw);
MinnDevelopment marked this conversation as resolved.
Show resolved Hide resolved

/**
* The current command name
*
Expand Down Expand Up @@ -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 <a href="https://support.discord.com/hc/en-us/articles/10123937946007" target="_blank">Age-Restricted Commands FAQ</a>
*/
boolean isNSFW();

/**
* Converts the provided {@link Command} into a CommandData instance.
*
Expand All @@ -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());
}
Expand Down Expand Up @@ -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;
Expand Down
Expand Up @@ -63,6 +63,10 @@ public interface SlashCommandData extends CommandData
@Override
SlashCommandData setGuildOnly(boolean guildOnly);

@Nonnull
@Override
SlashCommandData setNSFW(boolean nsfw);

/**
* Configure the description
*
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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")
Expand Down
Expand Up @@ -168,4 +168,8 @@ default CommandCreateAction addSubcommandGroups(@Nonnull Collection<? extends Su
@Override
@CheckReturnValue
CommandCreateAction setGuildOnly(boolean guildOnly);

@Nonnull
@Override
CommandCreateAction setNSFW(boolean nsfw);
}
Expand Up @@ -101,6 +101,23 @@ public interface CommandEditAction extends RestAction<Command>
@CheckReturnValue
CommandEditAction setGuildOnly(boolean guildOnly);

/**
* Sets whether this command should only be usable in NSFW (age-restricted) channels.
* <br>Default: false
*
* <p>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 <a href="https://support.discord.com/hc/en-us/articles/10123937946007" target="_blank">Age-Restricted Commands FAQ</a>
*/
@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.
* <br>By default, everyone can use this command ({@link DefaultMemberPermissions#ENABLED}). Additionally, a command can be disabled for everyone but admins via {@link DefaultMemberPermissions#DISABLED}.
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -135,6 +137,12 @@ public boolean isGuildOnly()
return guildOnly;
}

@Override
public boolean isNSFW()
{
return nsfw;
}

@Nonnull
@Override
public List<SubcommandData> getSubcommands()
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -59,7 +59,7 @@ public class CommandImpl implements Command
private final List<Command.SubcommandGroup> groups;
private final List<Command.Subcommand> 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;

Expand All @@ -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 <T> List<T> parseOptions(DataObject json, Predicate<DataObject> test, Function<DataObject, T> transform)
Expand Down Expand Up @@ -223,6 +224,12 @@ public boolean isGuildOnly()
return guildOnly;
}

@Override
public boolean isNSFW()
{
return nsfw;
}

@Override
public long getIdLong()
{
Expand Down
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -46,6 +46,9 @@ public class CommandEditActionImpl extends RestActionImpl<Command> 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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -127,6 +140,7 @@ public CommandEditAction setGuildOnly(boolean guildOnly)
public CommandEditAction setDefaultPermissions(@Nonnull DefaultMemberPermissions permission)
{
data.setDefaultPermissions(permission);
mask |= PERMISSIONS_SET;
return this;
}

Expand Down Expand Up @@ -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);
Expand Down