Skip to content

Commit

Permalink
[Feature] Age restricted (NSFW) application commands support (#2531)
Browse files Browse the repository at this point in the history
* add `nsfw` to data model & internal methods; add missing property

* add `nsfw` prop to command builders

* add `NsfwCommandAttribute` to Interaction Framework

* working state

* docs?
  • Loading branch information
Misha-133 authored Dec 19, 2022
1 parent 60956c7 commit 56b1a93
Show file tree
Hide file tree
Showing 23 changed files with 230 additions and 15 deletions.
5 changes: 5 additions & 0 deletions docs/guides/int_framework/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,10 @@ The amount of nesting you can do is realistically endless.
> If the nested class is marked with `Group`, as required for setting up subcommands, this example will not work.
> As mentioned before, subcommands cannot have seperate permissions from the top level command.
### NSFW Commands
Commands can be limited to only age restricted channels and DMs:

[!code-csharp[Nsfw-Permissions](samples/permissions/nsfw-permissions.cs)]

[permissions]: xref:Discord.GuildPermission

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[NsfwCommand(true)]
[SlashCommand("beautiful-code", "Get an image of perfect code")]
public async Task BeautifulCodeAsync(...)
{
...
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public IReadOnlyDictionary<string, string> DescriptionLocalizations
/// </summary>
public Optional<bool> IsDMEnabled { get; set; }

/// <summary>
/// Gets or sets whether or not this command is age restricted.
/// </summary>
public Optional<bool> IsNsfw { get; set; }

/// <summary>
/// Gets or sets the default permissions required by a user to execute this application command.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public string Name
/// </summary>
public bool IsDMEnabled { get; set; } = true;

/// <summary>
/// Gets or sets whether or not this command is age restricted.
/// </summary>
public bool IsNsfw{ get; set; } = false;

/// <summary>
/// Gets or sets the default permission required to use this slash command.
/// </summary>
Expand All @@ -68,7 +73,8 @@ public MessageCommandProperties Build()
IsDefaultPermission = IsDefaultPermission,
IsDMEnabled = IsDMEnabled,
DefaultMemberPermissions = DefaultMemberPermissions ?? Optional<GuildPermission>.Unspecified,
NameLocalizations = NameLocalizations
NameLocalizations = NameLocalizations,
IsNsfw = IsNsfw,
};

return props;
Expand Down Expand Up @@ -123,7 +129,7 @@ public MessageCommandBuilder WithNameLocalizations(IDictionary<string, string> n
}

/// <summary>
/// Sets whether or not this command can be used in dms
/// Sets whether or not this command can be used in dms.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is available in dms, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
Expand All @@ -133,6 +139,17 @@ public MessageCommandBuilder WithDMPermission(bool permission)
return this;
}

/// <summary>
/// Sets whether or not this command is age restricted.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is age restricted, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
public MessageCommandBuilder WithNsfw(bool permission)
{
IsNsfw = permission;
return this;
}

/// <summary>
/// Adds a new entry to the <see cref="NameLocalizations"/> collection.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public string Name
/// </summary>
public bool IsDMEnabled { get; set; } = true;

/// <summary>
/// Gets or sets whether or not this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;

/// <summary>
/// Gets or sets the default permission required to use this slash command.
/// </summary>
Expand All @@ -66,7 +71,8 @@ public UserCommandProperties Build()
IsDefaultPermission = IsDefaultPermission,
IsDMEnabled = IsDMEnabled,
DefaultMemberPermissions = DefaultMemberPermissions ?? Optional<GuildPermission>.Unspecified,
NameLocalizations = NameLocalizations
NameLocalizations = NameLocalizations,
IsNsfw = IsNsfw,
};

return props;
Expand Down Expand Up @@ -121,7 +127,7 @@ public UserCommandBuilder WithNameLocalizations(IDictionary<string, string> name
}

/// <summary>
/// Sets whether or not this command can be used in dms
/// Sets whether or not this command can be used in dms.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is available in dms, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
Expand All @@ -131,6 +137,17 @@ public UserCommandBuilder WithDMPermission(bool permission)
return this;
}

/// <summary>
/// Sets whether or not this command is age restricted.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is age restricted, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
public UserCommandBuilder WithNsfw(bool permission)
{
IsNsfw = permission;
return this;
}

/// <summary>
/// Adds a new entry to the <see cref="NameLocalizations"/> collection.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public interface IApplicationCommand : ISnowflakeEntity, IDeletable
/// </remarks>
bool IsEnabledInDm { get; }

/// <summary>
/// Indicates whether the command is age restricted.
/// </summary>
bool IsNsfw { get; }

/// <summary>
/// Set of default <see cref="GuildPermission"/> required to invoke the command.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public List<SlashCommandOptionBuilder> Options
/// Gets or sets whether or not this command can be used in DMs.
/// </summary>
public bool IsDMEnabled { get; set; } = true;

/// <summary>
/// Gets or sets whether or not this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;

/// <summary>
/// Gets or sets the default permission required to use this slash command.
Expand All @@ -110,7 +115,8 @@ public SlashCommandProperties Build()
NameLocalizations = _nameLocalizations,
DescriptionLocalizations = _descriptionLocalizations,
IsDMEnabled = IsDMEnabled,
DefaultMemberPermissions = DefaultMemberPermissions ?? Optional<GuildPermission>.Unspecified
DefaultMemberPermissions = DefaultMemberPermissions ?? Optional<GuildPermission>.Unspecified,
IsNsfw = IsNsfw,
};

if (Options != null && Options.Any())
Expand Down Expand Up @@ -161,7 +167,7 @@ public SlashCommandBuilder WithDefaultPermission(bool value)
}

/// <summary>
/// Sets whether or not this command can be used in dms
/// Sets whether or not this command can be used in dms.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is available in dms, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
Expand All @@ -171,6 +177,17 @@ public SlashCommandBuilder WithDMPermission(bool permission)
return this;
}

/// <summary>
/// Sets whether or not this command is age restricted.
/// </summary>
/// <param name="permission"><see langword="true"/> if the command is age restricted, otherwise <see langword="false"/>.</param>
/// <returns>The current builder.</returns>
public SlashCommandBuilder WithNsfw(bool permission)
{
IsNsfw = permission;
return this;
}

/// <summary>
/// Sets the default member permissions required to use this application command.
/// </summary>
Expand Down
25 changes: 25 additions & 0 deletions src/Discord.Net.Interactions/Attributes/NsfwCommandAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

namespace Discord.Interactions
{
/// <summary>
/// Sets the <see cref="IApplicationCommandInfo.IsNsfw"/> property of an application command or module.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class NsfwCommandAttribute : Attribute
{
/// <summary>
/// Gets whether or not this command is age restricted.
/// </summary>
public bool IsNsfw { get; }

/// <summary>
/// Sets the <see cref="IApplicationCommandInfo.IsNsfw"/> property of an application command or module.
/// </summary>
/// <param name="isNsfw">Whether or not this command is age restricted.</param>
public NsfwCommandAttribute(bool isNsfw)
{
IsNsfw = isNsfw;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public sealed class ContextCommandBuilder : CommandBuilder<ContextCommandInfo, C
/// </summary>
public bool IsEnabledInDm { get; set; } = true;

/// <summary>
/// Gets whether this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;

/// <summary>
/// Gets the default permissions needed for executing this command.
/// </summary>
Expand Down Expand Up @@ -95,6 +100,19 @@ public ContextCommandBuilder SetEnabledInDm(bool isEnabled)
return this;
}

/// <summary>
/// Sets <see cref="IsNsfw"/>.
/// </summary>
/// <param name="isNsfw">New value of the <see cref="IsNsfw"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ContextCommandBuilder SetNsfw(bool isNsfw)
{
IsNsfw = isNsfw;
return this;
}

/// <summary>
/// Sets <see cref="DefaultMemberPermissions"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public sealed class SlashCommandBuilder : CommandBuilder<SlashCommandInfo, Slash
/// </summary>
public bool IsEnabledInDm { get; set; } = true;

/// <summary>
/// Gets whether this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;

/// <summary>
/// Gets the default permissions needed for executing this command.
/// </summary>
Expand Down Expand Up @@ -95,6 +100,19 @@ public SlashCommandBuilder SetEnabledInDm(bool isEnabled)
return this;
}

/// <summary>
/// Sets <see cref="IsNsfw"/>.
/// </summary>
/// <param name="isNsfw">New value of the <see cref="IsNsfw"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public SlashCommandBuilder SetNsfw(bool isNsfw)
{
IsNsfw = isNsfw;
return this;
}

/// <summary>
/// Sets <see cref="DefaultMemberPermissions"/>.
/// </summary>
Expand Down
18 changes: 18 additions & 0 deletions src/Discord.Net.Interactions/Builders/ModuleBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public class ModuleBuilder
/// </summary>
public bool IsEnabledInDm { get; set; } = true;

/// <summary>
/// Gets whether this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;

/// <summary>
/// Gets the default permissions needed for executing this command.
/// </summary>
Expand Down Expand Up @@ -190,6 +195,19 @@ public ModuleBuilder SetEnabledInDm(bool isEnabled)
return this;
}

/// <summary>
/// Sets <see cref="IsNsfw"/>.
/// </summary>
/// <param name="isNsfw">New value of the <see cref="IsNsfw"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder SetNsfw(bool isNsfw)
{
IsNsfw = isNsfw;
return this;
}

/// <summary>
/// Sets <see cref="DefaultMemberPermissions"/>.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ private static void BuildModule (ModuleBuilder builder, TypeInfo typeInfo, Inter
case DontAutoRegisterAttribute dontAutoRegister:
builder.DontAutoRegister = true;
break;
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
default:
builder.AddAttributes(attribute);
break;
Expand Down Expand Up @@ -192,6 +195,9 @@ private static void BuildSlashCommand (SlashCommandBuilder builder, Func<IServic
case PreconditionAttribute precondition:
builder.WithPreconditions(precondition);
break;
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
default:
builder.WithAttributes(attribute);
break;
Expand Down Expand Up @@ -244,6 +250,9 @@ private static void BuildContextCommand (ContextCommandBuilder builder, Func<ISe
case PreconditionAttribute precondition:
builder.WithPreconditions(precondition);
break;
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
default:
builder.WithAttributes(attribute);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public abstract class ContextCommandInfo : CommandInfo<CommandParameterInfo>, IA
/// <inheritdoc/>
public bool IsEnabledInDm { get; }

/// <inheritdoc/>
public bool IsNsfw { get; }

/// <inheritdoc/>
public GuildPermission? DefaultMemberPermissions { get; }

Expand All @@ -37,6 +40,7 @@ internal ContextCommandInfo (Builders.ContextCommandBuilder builder, ModuleInfo
{
CommandType = builder.CommandType;
DefaultPermission = builder.DefaultPermission;
IsNsfw = builder.IsNsfw;
IsEnabledInDm = builder.IsEnabledInDm;
DefaultMemberPermissions = builder.DefaultMemberPermissions;
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class SlashCommandInfo : CommandInfo<SlashCommandParameterInfo>, IApplica
/// <inheritdoc/>
public bool IsEnabledInDm { get; }

/// <inheritdoc/>
public bool IsNsfw { get; }

/// <inheritdoc/>
public GuildPermission? DefaultMemberPermissions { get; }

Expand All @@ -48,6 +51,7 @@ internal SlashCommandInfo(Builders.SlashCommandBuilder builder, ModuleInfo modul
Description = builder.Description;
DefaultPermission = builder.DefaultPermission;
IsEnabledInDm = builder.IsEnabledInDm;
IsNsfw = builder.IsNsfw;
DefaultMemberPermissions = builder.DefaultMemberPermissions;
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
FlattenedParameters = FlattenParameters(Parameters).ToImmutableArray();
Expand Down
5 changes: 5 additions & 0 deletions src/Discord.Net.Interactions/Info/IApplicationCommandInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public interface IApplicationCommandInfo
/// </summary>
public bool IsEnabledInDm { get; }

/// <summary>
/// Gets whether this command can is age restricted.
/// </summary>
public bool IsNsfw { get; }

/// <summary>
/// Gets the default permissions needed for executing this command.
/// </summary>
Expand Down
Loading

0 comments on commit 56b1a93

Please sign in to comment.