[Feature] Initial user apps support (#2883)

* omg it kinda works somehow

* more things added

* a bit of xmldocs

* added interaction framework support

* working? IF

* more builder stuff

* space

* rename attribute to prevent conflict with `ContextType` enum

* context type

* moar features

* remove integration types

* trigger workflow

* modelzzzz

* `InteractionContextType`

* allow setting custom status with `SetGameAsync`

* bugzzz

* app permissions

* message interaction context

* hm

* push for cd

* structs lets goooo

* whoops forgot to change types

* whoops x2

* tweak some things

* xmldocs + missing prop + fix enabled in dm

* moar validations

* deprecate a bunch of stuffz

* disable moar obsolete warnings

* add IF sample

* Apply suggestions from code review

Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>

* Update src/Discord.Net.Rest/Entities/RestApplication.cs

Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>

---------

Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
This commit is contained in:
Mihail Gribkov
2024-03-19 00:24:05 +03:00
committed by GitHub
parent bfc8dc229e
commit 24a69785fe
63 changed files with 1257 additions and 300 deletions

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Discord.Interactions;
/// <summary>
/// Specifies context types this command can be executed in.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CommandContextTypeAttribute : Attribute
{
/// <summary>
/// Gets context types this command can be executed in.
/// </summary>
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
/// <summary>
/// Sets the <see cref="IApplicationCommandInfo.ContextTypes"/> property of an application command or module.
/// </summary>
/// <param name="contextTypes">Context types set for the command.</param>
public CommandContextTypeAttribute(params InteractionContextType[] contextTypes)
{
ContextTypes = contextTypes?.Distinct().ToImmutableArray()
?? throw new ArgumentNullException(nameof(contextTypes));
if (ContextTypes.Count == 0)
throw new ArgumentException("A command must have at least one supported context type.", nameof(contextTypes));
}
}

View File

@@ -6,6 +6,7 @@ namespace Discord.Interactions
/// Sets the <see cref="IApplicationCommandInfo.IsEnabledInDm"/> property of an application command or module.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
[Obsolete("This attribute will be deprecated soon. Configure with CommandContextTypes attribute instead.")]
public class EnabledInDmAttribute : Attribute
{
/// <summary>

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Discord.Interactions;
/// <summary>
/// Specifies install method for the command.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class IntegrationTypeAttribute : Attribute
{
/// <summary>
/// Gets integration install types for this command.
/// </summary>
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; }
/// <summary>
/// Sets the <see cref="IApplicationCommandInfo.IntegrationTypes"/> property of an application command or module.
/// </summary>
/// <param name="integrationTypes">Integration install types set for the command.</param>
public IntegrationTypeAttribute(params ApplicationIntegrationType[] integrationTypes)
{
IntegrationTypes = integrationTypes?.Distinct().ToImmutableArray()
?? throw new ArgumentNullException(nameof(integrationTypes));
if (integrationTypes.Length == 0)
throw new ArgumentException("A command must have at least one integration type.", nameof(integrationTypes));
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Discord.Interactions.Builders
{
@@ -35,7 +36,24 @@ namespace Discord.Interactions.Builders
/// </summary>
public GuildPermission? DefaultMemberPermissions { get; set; } = null;
internal ContextCommandBuilder(ModuleBuilder module) : base(module) { }
/// <summary>
/// Gets the install method for this command.
/// </summary>
public HashSet<ApplicationIntegrationType> IntegrationTypes { get; set; } = null;
/// <summary>
/// Gets the context types this command can be executed in.
/// </summary>
public HashSet<InteractionContextType> ContextTypes { get; set; } = null;
internal ContextCommandBuilder(ModuleBuilder module) : base(module)
{
IntegrationTypes = module.IntegrationTypes;
ContextTypes = module.ContextTypes;
#pragma warning disable CS0618 // Type or member is obsolete
IsEnabledInDm = module.IsEnabledInDm;
#pragma warning restore CS0618 // Type or member is obsolete
}
/// <summary>
/// Initializes a new <see cref="ContextCommandBuilder"/>.
@@ -126,6 +144,28 @@ namespace Discord.Interactions.Builders
return this;
}
/// <summary>
/// Sets the <see cref="IntegrationTypes"/> of this <see cref="ContextCommandBuilder"/>.
/// </summary>
/// <param name="integrationTypes">Install types for this command.</param>
/// <returns>The builder instance.</returns>
public ContextCommandBuilder WithIntegrationTypes(params ApplicationIntegrationType[] integrationTypes)
{
IntegrationTypes = new HashSet<ApplicationIntegrationType>(integrationTypes);
return this;
}
/// <summary>
/// Sets the <see cref="ContextTypes"/> of this <see cref="ContextCommandBuilder"/>.
/// </summary>
/// <param name="contextTypes">Context types the command can be executed in.</param>
/// <returns>The builder instance.</returns>
public ContextCommandBuilder WithContextTypes(params InteractionContextType[] contextTypes)
{
ContextTypes = new HashSet<InteractionContextType>(contextTypes);
return this;
}
internal override ContextCommandInfo Build(ModuleInfo module, InteractionService commandService) =>
ContextCommandInfo.Create(this, module, commandService);
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Discord.Interactions.Builders
{
@@ -35,7 +36,24 @@ namespace Discord.Interactions.Builders
/// </summary>
public GuildPermission? DefaultMemberPermissions { get; set; } = null;
internal SlashCommandBuilder(ModuleBuilder module) : base(module) { }
/// <summary>
/// Gets or sets the install method for this command.
/// </summary>
public HashSet<ApplicationIntegrationType> IntegrationTypes { get; set; } = null;
/// <summary>
/// Gets or sets the context types this command can be executed in.
/// </summary>
public HashSet<InteractionContextType> ContextTypes { get; set; } = null;
internal SlashCommandBuilder(ModuleBuilder module) : base(module)
{
IntegrationTypes = module.IntegrationTypes;
ContextTypes = module.ContextTypes;
#pragma warning disable CS0618 // Type or member is obsolete
IsEnabledInDm = module.IsEnabledInDm;
#pragma warning restore CS0618 // Type or member is obsolete
}
/// <summary>
/// Initializes a new <see cref="SlashCommandBuilder"/>.
@@ -126,6 +144,32 @@ namespace Discord.Interactions.Builders
return this;
}
/// <summary>
/// Sets the <see cref="IntegrationTypes"/> on this <see cref="SlashCommandBuilder"/>.
/// </summary>
/// <param name="integrationTypes">Install types for this command.</param>
/// <returns>The builder instance.</returns>
public SlashCommandBuilder WithIntegrationTypes(params ApplicationIntegrationType[] integrationTypes)
{
IntegrationTypes = integrationTypes is not null
? new HashSet<ApplicationIntegrationType>(integrationTypes)
: null;
return this;
}
/// <summary>
/// Sets the <see cref="ContextTypes"/> on this <see cref="SlashCommandBuilder"/>.
/// </summary>
/// <param name="contextTypes">Context types the command can be executed in.</param>
/// <returns>The builder instance.</returns>
public SlashCommandBuilder WithContextTypes(params InteractionContextType[] contextTypes)
{
ContextTypes = contextTypes is not null
? new HashSet<InteractionContextType>(contextTypes)
: null;
return this;
}
internal override SlashCommandInfo Build(ModuleInfo module, InteractionService commandService) =>
new SlashCommandInfo(this, module, commandService);
}

View File

@@ -51,12 +51,13 @@ namespace Discord.Interactions.Builders
/// <summary>
/// Gets and sets the default permission of this module.
/// </summary>
[Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")]
[Obsolete($"To be deprecated soon, use {nameof(ContextTypes)} and {nameof(DefaultMemberPermissions)} instead.")]
public bool DefaultPermission { get; set; } = true;
/// <summary>
/// Gets whether this command can be used in DMs.
/// </summary>
[Obsolete("This property will be deprecated soon. Use ContextTypes instead.")]
public bool IsEnabledInDm { get; set; } = true;
/// <summary>
@@ -114,6 +115,16 @@ namespace Discord.Interactions.Builders
/// </summary>
public IReadOnlyList<ModalCommandBuilder> ModalCommands => _modalCommands;
/// <summary>
/// Gets or sets the install method for this command.
/// </summary>
public HashSet<ApplicationIntegrationType> IntegrationTypes { get; set; } = null;
/// <summary>
/// Gets or sets the context types this command can be executed in.
/// </summary>
public HashSet<InteractionContextType> ContextTypes { get; set; } = null;
internal TypeInfo TypeInfo { get; set; }
internal ModuleBuilder(InteractionService interactionService, ModuleBuilder parent = null)
@@ -189,6 +200,7 @@ namespace Discord.Interactions.Builders
/// <returns>
/// The builder instance.
/// </returns>
[Obsolete("This method will be deprecated soon. Use WithContextTypes instead.")]
public ModuleBuilder SetEnabledInDm(bool isEnabled)
{
IsEnabledInDm = isEnabled;
@@ -423,6 +435,28 @@ namespace Discord.Interactions.Builders
return this;
}
/// <summary>
/// Sets the <see cref="IntegrationTypes"/> on this <see cref="ModuleBuilder"/>.
/// </summary>
/// <param name="integrationTypes">Install types for this command.</param>
/// <returns>The builder instance.</returns>
public ModuleBuilder WithIntegrationTypes(params ApplicationIntegrationType[] integrationTypes)
{
IntegrationTypes = new HashSet<ApplicationIntegrationType>(integrationTypes);
return this;
}
/// <summary>
/// Sets the <see cref="ContextTypes"/> on this <see cref="ModuleBuilder"/>.
/// </summary>
/// <param name="contextTypes">Context types the command can be executed in.</param>
/// <returns>The builder instance.</returns>
public ModuleBuilder WithContextTypes(params InteractionContextType[] contextTypes)
{
ContextTypes = new HashSet<InteractionContextType>(contextTypes);
return this;
}
internal ModuleInfo Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent = null)
{
if (TypeInfo is not null && ModuleClassBuilder.IsValidModuleDefinition(TypeInfo))

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
@@ -87,11 +88,13 @@ namespace Discord.Interactions.Builders
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
case EnabledInDmAttribute enabledInDm:
{
{
builder.IsEnabledInDm = enabledInDm.IsEnabled;
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
case DefaultMemberPermissionsAttribute memberPermission:
{
builder.DefaultMemberPermissions = memberPermission.Permissions;
@@ -106,6 +109,12 @@ namespace Discord.Interactions.Builders
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
case CommandContextTypeAttribute contextType:
builder.WithContextTypes(contextType.ContextTypes?.ToArray());
break;
case IntegrationTypeAttribute integrationType:
builder.WithIntegrationTypes(integrationType.IntegrationTypes?.ToArray());
break;
default:
builder.AddAttributes(attribute);
break;
@@ -185,12 +194,12 @@ namespace Discord.Interactions.Builders
builder.DefaultPermission = defaultPermission.IsDefaultPermission;
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
case EnabledInDmAttribute enabledInDm:
{
builder.IsEnabledInDm = enabledInDm.IsEnabled;
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
case DefaultMemberPermissionsAttribute memberPermission:
{
builder.DefaultMemberPermissions = memberPermission.Permissions;
@@ -202,6 +211,12 @@ namespace Discord.Interactions.Builders
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
case CommandContextTypeAttribute contextType:
builder.WithContextTypes(contextType.ContextTypes.ToArray());
break;
case IntegrationTypeAttribute integrationType:
builder.WithIntegrationTypes(integrationType.IntegrationTypes.ToArray());
break;
default:
builder.WithAttributes(attribute);
break;
@@ -242,12 +257,12 @@ namespace Discord.Interactions.Builders
builder.DefaultPermission = defaultPermission.IsDefaultPermission;
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
case EnabledInDmAttribute enabledInDm:
{
builder.IsEnabledInDm = enabledInDm.IsEnabled;
}
break;
#pragma warning restore CS0618 // Type or member is obsolete
case DefaultMemberPermissionsAttribute memberPermission:
{
builder.DefaultMemberPermissions = memberPermission.Permissions;
@@ -259,6 +274,12 @@ namespace Discord.Interactions.Builders
case NsfwCommandAttribute nsfwCommand:
builder.SetNsfw(nsfwCommand.IsNsfw);
break;
case CommandContextTypeAttribute contextType:
builder.WithContextTypes(contextType.ContextTypes.ToArray());
break;
case IntegrationTypeAttribute integrationType:
builder.WithIntegrationTypes(integrationType.IntegrationTypes.ToArray());
break;
default:
builder.WithAttributes(attribute);
break;

View File

@@ -26,6 +26,12 @@ namespace Discord.Interactions
/// <inheritdoc/>
public GuildPermission? DefaultMemberPermissions { get; }
/// <inheritdoc/>
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
/// <inheritdoc/>
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; }
/// <inheritdoc/>
public override IReadOnlyList<CommandParameterInfo> Parameters { get; }
@@ -46,6 +52,8 @@ namespace Discord.Interactions
IsEnabledInDm = builder.IsEnabledInDm;
DefaultMemberPermissions = builder.DefaultMemberPermissions;
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
ContextTypes = builder.ContextTypes?.ToImmutableArray();
IntegrationTypes = builder.IntegrationTypes?.ToImmutableArray();
}
internal static ContextCommandInfo Create(Builders.ContextCommandBuilder builder, ModuleInfo module, InteractionService commandService)

View File

@@ -46,6 +46,12 @@ namespace Discord.Interactions
/// </summary>
public IReadOnlyList<SlashCommandParameterInfo> FlattenedParameters { get; }
/// <inheritdoc/>
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
/// <inheritdoc/>
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; }
internal SlashCommandInfo(Builders.SlashCommandBuilder builder, ModuleInfo module, InteractionService commandService) : base(builder, module, commandService)
{
Description = builder.Description;
@@ -57,6 +63,8 @@ namespace Discord.Interactions
DefaultMemberPermissions = builder.DefaultMemberPermissions;
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
FlattenedParameters = FlattenParameters(Parameters).ToImmutableArray();
ContextTypes = builder.ContextTypes?.ToImmutableArray();
IntegrationTypes = builder.IntegrationTypes?.ToImmutableArray();
for (var i = 0; i < FlattenedParameters.Count - 1; i++)
if (!FlattenedParameters.ElementAt(i).IsRequired && FlattenedParameters.ElementAt(i + 1).IsRequired)

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Discord.Interactions
{
@@ -37,5 +38,15 @@ namespace Discord.Interactions
/// Gets the default permissions needed for executing this command.
/// </summary>
public GuildPermission? DefaultMemberPermissions { get; }
/// <summary>
/// Gets the context types this command can be executed in.
/// </summary>
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
/// <summary>
/// Gets the install methods for this command.
/// </summary>
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; }
}
}

View File

@@ -117,6 +117,16 @@ namespace Discord.Interactions
/// </summary>
public bool DontAutoRegister { get; }
/// <summary>
/// Gets the context types commands in this module can be executed in.
/// </summary>
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
/// <summary>
/// Gets the install method for commands in this module.
/// </summary>
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; }
internal ModuleInfo(ModuleBuilder builder, InteractionService commandService, IServiceProvider services, ModuleInfo parent = null)
{
CommandService = commandService;
@@ -129,7 +139,9 @@ namespace Discord.Interactions
DefaultPermission = builder.DefaultPermission;
#pragma warning restore CS0618 // Type or member is obsolete
IsNsfw = builder.IsNsfw;
#pragma warning disable CS0618 // Type or member is obsolete
IsEnabledInDm = builder.IsEnabledInDm;
#pragma warning restore CS0618 // Type or member is obsolete
DefaultMemberPermissions = BuildDefaultMemberPermissions(builder);
SlashCommands = BuildSlashCommands(builder).ToImmutableArray();
ContextCommands = BuildContextCommands(builder).ToImmutableArray();
@@ -141,6 +153,8 @@ namespace Discord.Interactions
Preconditions = BuildPreconditions(builder).ToImmutableArray();
IsTopLevelGroup = IsSlashGroup && CheckTopLevel(parent);
DontAutoRegister = builder.DontAutoRegister;
ContextTypes = builder.ContextTypes?.ToImmutableArray();
IntegrationTypes = builder.IntegrationTypes?.ToImmutableArray();
GroupedPreconditions = Preconditions.ToLookup(x => x.Group, x => x, StringComparer.Ordinal);
}

View File

@@ -53,9 +53,17 @@ namespace Discord.Interactions
Name = commandInfo.Name,
Description = commandInfo.Description,
IsDefaultPermission = commandInfo.DefaultPermission,
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = commandInfo.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
IsNsfw = commandInfo.IsNsfw,
DefaultMemberPermissions = ((commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0)).SanitizeGuildPermissions(),
IntegrationTypes = commandInfo.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(commandInfo.IntegrationTypes)
: null,
ContextTypes = commandInfo.ContextTypes is not null
? new HashSet<InteractionContextType>(commandInfo.ContextTypes)
: null,
}.WithNameLocalizations(localizationManager?.GetAllNames(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty)
.WithDescriptionLocalizations(localizationManager?.GetAllDescriptions(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty)
.Build();
@@ -82,7 +90,7 @@ namespace Discord.Interactions
Options = commandInfo.FlattenedParameters?.Select(x => x.ToApplicationCommandOptionProps())
?.ToList(),
NameLocalizations = localizationManager?.GetAllNames(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty,
DescriptionLocalizations = localizationManager?.GetAllDescriptions(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty
DescriptionLocalizations = localizationManager?.GetAllDescriptions(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty,
};
}
@@ -98,8 +106,16 @@ namespace Discord.Interactions
Name = commandInfo.Name,
IsDefaultPermission = commandInfo.DefaultPermission,
DefaultMemberPermissions = ((commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0)).SanitizeGuildPermissions(),
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = commandInfo.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
IsNsfw = commandInfo.IsNsfw,
IntegrationTypes = commandInfo.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(commandInfo.IntegrationTypes)
: null,
ContextTypes = commandInfo.ContextTypes is not null
? new HashSet<InteractionContextType>(commandInfo.ContextTypes)
: null,
}
.WithNameLocalizations(localizationManager?.GetAllNames(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty)
.Build(),
@@ -109,7 +125,15 @@ namespace Discord.Interactions
IsDefaultPermission = commandInfo.DefaultPermission,
DefaultMemberPermissions = ((commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0)).SanitizeGuildPermissions(),
IsNsfw = commandInfo.IsNsfw,
IsDMEnabled = commandInfo.IsEnabledInDm
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = commandInfo.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
IntegrationTypes = commandInfo.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(commandInfo.IntegrationTypes)
: null,
ContextTypes = commandInfo.ContextTypes is not null
? new HashSet<InteractionContextType>(commandInfo.ContextTypes)
: null,
}
.WithNameLocalizations(localizationManager?.GetAllNames(commandPath, LocalizationTarget.Command) ?? ImmutableDictionary<string, string>.Empty)
.Build(),
@@ -165,10 +189,16 @@ namespace Discord.Interactions
Description = moduleInfo.Description,
#pragma warning disable CS0618 // Type or member is obsolete
IsDefaultPermission = moduleInfo.DefaultPermission,
#pragma warning restore CS0618 // Type or member is obsolete
IsDMEnabled = moduleInfo.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
IsNsfw = moduleInfo.IsNsfw,
DefaultMemberPermissions = moduleInfo.DefaultMemberPermissions
DefaultMemberPermissions = moduleInfo.DefaultMemberPermissions,
IntegrationTypes = moduleInfo.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(moduleInfo.IntegrationTypes)
: null,
ContextTypes = moduleInfo.ContextTypes is not null
? new HashSet<InteractionContextType>(moduleInfo.ContextTypes)
: null,
}
.WithNameLocalizations(localizationManager?.GetAllNames(modulePath, LocalizationTarget.Group) ?? ImmutableDictionary<string, string>.Empty)
.WithDescriptionLocalizations(localizationManager?.GetAllDescriptions(modulePath, LocalizationTarget.Group) ?? ImmutableDictionary<string, string>.Empty)
@@ -230,11 +260,19 @@ namespace Discord.Interactions
Description = command.Description,
IsDefaultPermission = command.IsDefaultPermission,
DefaultMemberPermissions = command.DefaultMemberPermissions.RawValue == 0 ? new Optional<GuildPermission>() : (GuildPermission)command.DefaultMemberPermissions.RawValue,
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = command.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
IsNsfw = command.IsNsfw,
Options = command.Options?.Select(x => x.ToApplicationCommandOptionProps())?.ToList() ?? Optional<List<ApplicationCommandOptionProperties>>.Unspecified,
NameLocalizations = command.NameLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
DescriptionLocalizations = command.DescriptionLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
ContextTypes = command.ContextTypes is not null
? new HashSet<InteractionContextType>(command.ContextTypes)
: Optional<HashSet<InteractionContextType>>.Unspecified,
IntegrationTypes = command.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(command.IntegrationTypes)
: Optional<HashSet<ApplicationIntegrationType>>.Unspecified,
},
ApplicationCommandType.User => new UserCommandProperties
{
@@ -242,9 +280,17 @@ namespace Discord.Interactions
IsDefaultPermission = command.IsDefaultPermission,
DefaultMemberPermissions = command.DefaultMemberPermissions.RawValue == 0 ? new Optional<GuildPermission>() : (GuildPermission)command.DefaultMemberPermissions.RawValue,
IsNsfw = command.IsNsfw,
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = command.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
NameLocalizations = command.NameLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
DescriptionLocalizations = command.DescriptionLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty
DescriptionLocalizations = command.DescriptionLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
ContextTypes = command.ContextTypes is not null
? new HashSet<InteractionContextType>(command.ContextTypes)
: Optional<HashSet<InteractionContextType>>.Unspecified,
IntegrationTypes = command.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(command.IntegrationTypes)
: Optional<HashSet<ApplicationIntegrationType>>.Unspecified,
},
ApplicationCommandType.Message => new MessageCommandProperties
{
@@ -252,9 +298,17 @@ namespace Discord.Interactions
IsDefaultPermission = command.IsDefaultPermission,
DefaultMemberPermissions = command.DefaultMemberPermissions.RawValue == 0 ? new Optional<GuildPermission>() : (GuildPermission)command.DefaultMemberPermissions.RawValue,
IsNsfw = command.IsNsfw,
#pragma warning disable CS0618 // Type or member is obsolete
IsDMEnabled = command.IsEnabledInDm,
#pragma warning restore CS0618 // Type or member is obsolete
NameLocalizations = command.NameLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
DescriptionLocalizations = command.DescriptionLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty
DescriptionLocalizations = command.DescriptionLocalizations?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty,
ContextTypes = command.ContextTypes is not null
? new HashSet<InteractionContextType>(command.ContextTypes)
: Optional<HashSet<InteractionContextType>>.Unspecified,
IntegrationTypes = command.IntegrationTypes is not null
? new HashSet<ApplicationIntegrationType>(command.IntegrationTypes)
: Optional<HashSet<ApplicationIntegrationType>>.Unspecified,
},
_ => throw new InvalidOperationException($"Cannot create command properties for command type {command.Type}"),
};