diff --git a/DisCatSharp.ApplicationCommands/Workers/ApplicationCommandWorker.cs b/DisCatSharp.ApplicationCommands/Workers/ApplicationCommandWorker.cs
index 1f0b7d9a3..dd0ac9756 100644
--- a/DisCatSharp.ApplicationCommands/Workers/ApplicationCommandWorker.cs
+++ b/DisCatSharp.ApplicationCommands/Workers/ApplicationCommandWorker.cs
@@ -1,383 +1,383 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
namespace DisCatSharp.ApplicationCommands
{
///
/// Represents a .
///
internal class CommandWorker
{
///
/// Parses context menu application commands.
///
/// The type.
/// List of method infos.
/// The optional command translations.
/// Too much.
internal static Task<
(
List applicationCommands,
List> commandTypeSources,
List contextMenuCommands
)
> ParseContextMenuCommands(Type type, IEnumerable methods, List translator = null)
{
List commands = new();
List> commandTypeSources = new();
List contextMenuCommands = new();
foreach (var contextMethod in methods)
{
var contextAttribute = contextMethod.GetCustomAttribute();
DiscordApplicationCommandLocalization nameLocalizations = null;
var commandTranslation = translator?.Single(c => c.Name == contextAttribute.Name && c.Type == contextAttribute.Type);
if (commandTranslation != null)
nameLocalizations = commandTranslation.NameTranslations;
var command = new DiscordApplicationCommand(contextAttribute.Name, null, null, contextAttribute.DefaultPermission, contextAttribute.Type, nameLocalizations);
var parameters = contextMethod.GetParameters();
if (parameters.Length == 0 || parameters == null || !ReferenceEquals(parameters.FirstOrDefault()?.ParameterType, typeof(ContextMenuContext)))
throw new ArgumentException($"The first argument must be a ContextMenuContext!");
if (parameters.Length > 1)
throw new ArgumentException($"A context menu cannot have parameters!");
contextMenuCommands.Add(new ContextMenuCommand { Method = contextMethod, Name = contextAttribute.Name });
commands.Add(command);
commandTypeSources.Add(new KeyValuePair(type, type));
}
return Task.FromResult((commands, commandTypeSources, contextMenuCommands));
}
///
/// Parses single application commands.
///
/// The type.
/// List of method infos.
/// The optional guild id.
/// The optional command translations.
/// Too much.
internal static async Task<
(
List applicationCommands,
List> commandTypeSources,
List commandMethods
)
> ParseBasicSlashCommandsAsync(Type type, IEnumerable methods, ulong? guildId = null, List translator = null)
{
List commands = new();
List> commandTypeSources = new();
List commandMethods = new();
foreach (var method in methods)
{
var commandattribute = method.GetCustomAttribute();
var parameters = method.GetParameters();
if (parameters.Length == 0 || parameters == null || !ReferenceEquals(parameters.FirstOrDefault()?.ParameterType, typeof(InteractionContext)))
throw new ArgumentException($"The first argument must be an InteractionContext!");
parameters = parameters.Skip(1).ToArray();
var options = await ApplicationCommandsExtension.ParseParametersAsync(parameters, guildId);
commandMethods.Add(new CommandMethod { Method = method, Name = commandattribute.Name });
DiscordApplicationCommandLocalization nameLocalizations = null;
DiscordApplicationCommandLocalization descriptionLocalizations = null;
List localizisedOptions = null;
var commandTranslation = translator?.Single(c => c.Name == commandattribute.Name && c.Type == ApplicationCommandType.ChatInput);
if (commandTranslation != null && commandTranslation.Options != null)
{
localizisedOptions = new List(options.Count);
foreach (var option in options)
{
- List choices = option.Choices != null ? new List(option.Choices.Count()) : null;
+ List choices = option.Choices != null ? new List(option.Choices.Count) : null;
if (option.Choices != null)
{
foreach (var choice in option.Choices)
{
choices.Add(new DiscordApplicationCommandOptionChoice(choice.Name, choice.Value, commandTranslation.Options.Single(o => o.Name == option.Name).Choices.Single(c => c.Name == choice.Name).NameTranslations));
}
}
localizisedOptions.Add(new DiscordApplicationCommandOption(option.Name, option.Description, option.Type, option.Required,
choices, option.Options, option.ChannelTypes, option.AutoComplete, option.MinimumValue, option.MaximumValue,
commandTranslation.Options.Single(o => o.Name == option.Name).NameTranslations, commandTranslation.Options.Single(o => o.Name == option.Name).DescriptionTranslations
));
}
nameLocalizations = commandTranslation.NameTranslations;
descriptionLocalizations = commandTranslation.DescriptionTranslations;
}
var payload = new DiscordApplicationCommand(commandattribute.Name, commandattribute.Description, localizisedOptions ?? options, commandattribute.DefaultPermission, ApplicationCommandType.ChatInput, nameLocalizations, descriptionLocalizations);
commands.Add(payload);
commandTypeSources.Add(new KeyValuePair(type, type));
}
return (commands, commandTypeSources, commandMethods);
}
}
///
/// Represents a .
///
internal class NestedCommandWorker
{
///
/// Parses application command groups.
///
/// The type.
/// List of type infos.
/// The optional guild id.
/// The optional group translations.
/// Too much.
internal static async Task<
(
List applicationCommands,
List> commandTypeSources,
List singletonModules,
List groupCommands,
List subGroupCommands
)
> ParseSlashGroupsAsync(Type type, List types, ulong? guildId = null, List translator = null)
{
List commands = new();
List> commandTypeSources = new();
List groupCommands = new();
List subGroupCommands = new();
List singletonModules = new();
//Handles groups
foreach (var subclassinfo in types)
{
//Gets the attribute and methods in the group
var groupAttribute = subclassinfo.GetCustomAttribute();
var submethods = subclassinfo.DeclaredMethods.Where(x => x.GetCustomAttribute() != null).ToList();
var subclasses = subclassinfo.DeclaredNestedTypes.Where(x => x.GetCustomAttribute() != null).ToList();
if (subclasses.Any() && submethods.Any())
{
throw new ArgumentException("Slash command groups cannot have both subcommands and subgroups!");
}
DiscordApplicationCommandLocalization nameLocalizations = null;
DiscordApplicationCommandLocalization descriptionLocalizations = null;
if (translator != null)
{
var commandTranslation = translator.Single(c => c.Name == groupAttribute.Name);
if (commandTranslation != null)
{
nameLocalizations = commandTranslation.NameTranslations;
descriptionLocalizations = commandTranslation.DescriptionTranslations;
}
}
//Initializes the command
var payload = new DiscordApplicationCommand(groupAttribute.Name, groupAttribute.Description, defaultPermission: groupAttribute.DefaultPermission, nameLocalizations: nameLocalizations, descriptionLocalizations: descriptionLocalizations);
commandTypeSources.Add(new KeyValuePair(type, type));
var commandmethods = new List>();
//Handles commands in the group
foreach (var submethod in submethods)
{
var commandAttribute = submethod.GetCustomAttribute();
//Gets the paramaters and accounts for InteractionContext
var parameters = submethod.GetParameters();
if (parameters.Length == 0 || parameters == null || !ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
throw new ArgumentException($"The first argument must be an InteractionContext!");
parameters = parameters.Skip(1).ToArray();
var options = await ApplicationCommandsExtension.ParseParametersAsync(parameters, guildId);
DiscordApplicationCommandLocalization subNameLocalizations = null;
DiscordApplicationCommandLocalization subDescriptionLocalizations = null;
List localizisedOptions = null;
var commandTranslation = translator?.Single(c => c.Name == payload.Name);
if (commandTranslation?.Commands != null)
{
var subCommandTranslation = commandTranslation.Commands.Single(sc => sc.Name == commandAttribute.Name);
if (subCommandTranslation.Options != null)
{
localizisedOptions = new List(options.Count);
foreach (var option in options)
{
- List choices = option.Choices != null ? new List(option.Choices.Count()) : null;
+ List choices = option.Choices != null ? new List(option.Choices.Count) : null;
if (option.Choices != null)
{
foreach (var choice in option.Choices)
{
choices.Add(new DiscordApplicationCommandOptionChoice(choice.Name, choice.Value, subCommandTranslation.Options.Single(o => o.Name == option.Name).Choices.Single(c => c.Name == choice.Name).NameTranslations));
}
}
localizisedOptions.Add(new DiscordApplicationCommandOption(option.Name, option.Description, option.Type, option.Required,
choices, option.Options, option.ChannelTypes, option.AutoComplete, option.MinimumValue, option.MaximumValue,
subCommandTranslation.Options.Single(o => o.Name == option.Name).NameTranslations, subCommandTranslation.Options.Single(o => o.Name == option.Name).DescriptionTranslations
));
}
}
subNameLocalizations = subCommandTranslation.NameTranslations;
subDescriptionLocalizations = subCommandTranslation.DescriptionTranslations;
}
//Creates the subcommand and adds it to the main command
var subpayload = new DiscordApplicationCommandOption(commandAttribute.Name, commandAttribute.Description, ApplicationCommandOptionType.SubCommand, null, null, localizisedOptions ?? options, nameLocalizations: subNameLocalizations, descriptionLocalizations: subDescriptionLocalizations);
payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options?.Append(subpayload) ?? new[] { subpayload }, payload.DefaultPermission, nameLocalizations: payload.NameLocalizations, descriptionLocalizations: payload.DescriptionLocalizations);
commandTypeSources.Add(new KeyValuePair(subclassinfo, type));
//Adds it to the method lists
commandmethods.Add(new KeyValuePair(commandAttribute.Name, submethod));
groupCommands.Add(new GroupCommand { Name = groupAttribute.Name, Methods = commandmethods });
}
var command = new SubGroupCommand { Name = groupAttribute.Name };
//Handles subgroups
foreach (var subclass in subclasses)
{
var subGroupAttribute = subclass.GetCustomAttribute();
var subsubmethods = subclass.DeclaredMethods.Where(x => x.GetCustomAttribute() != null);
var options = new List();
var currentMethods = new List>();
DiscordApplicationCommandLocalization subNameLocalizations = null;
DiscordApplicationCommandLocalization subDescriptionLocalizations = null;
if (translator != null)
{
var commandTranslation = translator.Single(c => c.Name == payload.Name);
if (commandTranslation != null && commandTranslation.SubGroups != null)
{
var subCommandTranslation = commandTranslation.SubGroups.Single(sc => sc.Name == subGroupAttribute.Name);
if (subCommandTranslation != null)
{
subNameLocalizations = subCommandTranslation.NameTranslations;
subDescriptionLocalizations = subCommandTranslation.DescriptionTranslations;
}
}
}
//Similar to the one for regular groups
foreach (var subsubmethod in subsubmethods)
{
var suboptions = new List();
var commatt = subsubmethod.GetCustomAttribute();
var parameters = subsubmethod.GetParameters();
if (parameters.Length == 0 || parameters == null || !ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
throw new ArgumentException($"The first argument must be an InteractionContext!");
parameters = parameters.Skip(1).ToArray();
suboptions = suboptions.Concat(await ApplicationCommandsExtension.ParseParametersAsync(parameters, guildId)).ToList();
DiscordApplicationCommandLocalization subSubNameLocalizations = null;
DiscordApplicationCommandLocalization subSubDescriptionLocalizations = null;
List localizisedOptions = null;
var commandTranslation = translator?.Single(c => c.Name == payload.Name);
var subCommandTranslation = commandTranslation?.SubGroups?.Single(sc => sc.Name == commatt.Name);
var subSubCommandTranslation = subCommandTranslation?.Commands.Single(sc => sc.Name == commatt.Name);
if (subSubCommandTranslation != null && subSubCommandTranslation.Options != null)
{
localizisedOptions = new List(suboptions.Count);
foreach (var option in suboptions)
{
List choices = option.Choices != null ? new List(option.Choices.Count) : null;
if (option.Choices != null)
{
foreach (var choice in option.Choices)
{
choices.Add(new DiscordApplicationCommandOptionChoice(choice.Name, choice.Value, subSubCommandTranslation.Options.Single(o => o.Name == option.Name).Choices.Single(c => c.Name == choice.Name).NameTranslations));
}
}
localizisedOptions.Add(new DiscordApplicationCommandOption(option.Name, option.Description, option.Type, option.Required,
choices, option.Options, option.ChannelTypes, option.AutoComplete, option.MinimumValue, option.MaximumValue,
subSubCommandTranslation.Options.Single(o => o.Name == option.Name).NameTranslations, subSubCommandTranslation.Options.Single(o => o.Name == option.Name).DescriptionTranslations
));
}
subSubNameLocalizations = subSubCommandTranslation.NameTranslations;
subSubDescriptionLocalizations = subSubCommandTranslation.DescriptionTranslations;
}
var subsubpayload = new DiscordApplicationCommandOption(commatt.Name, commatt.Description, ApplicationCommandOptionType.SubCommand, null, null, localizisedOptions ?? suboptions, nameLocalizations: subSubNameLocalizations, descriptionLocalizations: subSubDescriptionLocalizations);
options.Add(subsubpayload);
commandmethods.Add(new KeyValuePair(commatt.Name, subsubmethod));
currentMethods.Add(new KeyValuePair(commatt.Name, subsubmethod));
}
//Adds the group to the command and method lists
var subpayload = new DiscordApplicationCommandOption(subGroupAttribute.Name, subGroupAttribute.Description, ApplicationCommandOptionType.SubCommandGroup, null, null, options, nameLocalizations: subNameLocalizations, descriptionLocalizations: subDescriptionLocalizations);
command.SubCommands.Add(new GroupCommand { Name = subGroupAttribute.Name, Methods = currentMethods });
payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options?.Append(subpayload) ?? new[] { subpayload }, payload.DefaultPermission, nameLocalizations: payload.NameLocalizations, descriptionLocalizations: payload.DescriptionLocalizations);
commandTypeSources.Add(new KeyValuePair(subclass, type));
//Accounts for lifespans for the sub group
if (subclass.GetCustomAttribute() != null && subclass.GetCustomAttribute().Lifespan == ApplicationCommandModuleLifespan.Singleton)
{
singletonModules.Add(ApplicationCommandsExtension.CreateInstance(subclass, ApplicationCommandsExtension.Configuration?.ServiceProvider));
}
}
if (command.SubCommands.Any()) subGroupCommands.Add(command);
commands.Add(payload);
//Accounts for lifespans
if (subclassinfo.GetCustomAttribute() != null && subclassinfo.GetCustomAttribute().Lifespan == ApplicationCommandModuleLifespan.Singleton)
{
singletonModules.Add(ApplicationCommandsExtension.CreateInstance(subclassinfo, ApplicationCommandsExtension.Configuration?.ServiceProvider));
}
}
return (commands, commandTypeSources, singletonModules, groupCommands, subGroupCommands);
}
}
}
diff --git a/DisCatSharp.ApplicationCommands/Workers/RegistrationWorker.cs b/DisCatSharp.ApplicationCommands/Workers/RegistrationWorker.cs
index db06c8652..f285db9ac 100644
--- a/DisCatSharp.ApplicationCommands/Workers/RegistrationWorker.cs
+++ b/DisCatSharp.ApplicationCommands/Workers/RegistrationWorker.cs
@@ -1,361 +1,361 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DisCatSharp.Common;
using DisCatSharp.Entities;
using DisCatSharp.Exceptions;
using Microsoft.Extensions.Logging;
namespace DisCatSharp.ApplicationCommands
{
///
/// Represents a .
///
internal class RegistrationWorker
{
///
/// Registers the global commands.
///
/// The command list.
/// A list of registered commands.
internal static async Task> RegisterGlobalCommandsAsync(List commands)
{
var globalCommandsOverwriteList = BuildGlobalOverwriteList(commands);
var globalCommandsCreateList = BuildGlobalCreateList(commands);
var globalCommandsDeleteList = BuildGlobalDeleteList(commands);
if (globalCommandsCreateList.NotEmptyAndNotNull() && globalCommandsOverwriteList.EmptyOrNull())
{
var cmds = await ApplicationCommandsExtension.ClientInternal.BulkOverwriteGlobalApplicationCommandsAsync(globalCommandsCreateList);
commands.AddRange(cmds);
}
else if (globalCommandsCreateList.EmptyOrNull() && globalCommandsOverwriteList.NotEmptyAndNotNull())
{
List overwriteList = new();
foreach (var overwrite in globalCommandsOverwriteList)
{
var cmd = overwrite.Value;
cmd.Id = overwrite.Key;
overwriteList.Add(cmd);
}
var discordBackendCommands = await ApplicationCommandsExtension.ClientInternal.BulkOverwriteGlobalApplicationCommandsAsync(overwriteList);
commands.AddRange(discordBackendCommands);
}
else if (globalCommandsCreateList.NotEmptyAndNotNull() && globalCommandsOverwriteList.NotEmptyAndNotNull())
{
foreach (var cmd in globalCommandsCreateList)
{
var discordBackendCommand = await ApplicationCommandsExtension.ClientInternal.CreateGlobalApplicationCommandAsync(cmd);
commands.Add(discordBackendCommand);
}
foreach (var cmd in globalCommandsOverwriteList)
{
var command = cmd.Value;
var discordBackendCommand = await ApplicationCommandsExtension.ClientInternal.EditGlobalApplicationCommandAsync(cmd.Key, action =>
{
action.Name = command.Name;
action.NameLocalizations = command.NameLocalizations;
action.Description = command.Description;
action.DescriptionLocalizations = command.DescriptionLocalizations;
if(command.Options != null && command.Options.Any())
action.Options = Entities.Optional.FromValue(command.Options);
action.DefaultPermission = command.DefaultPermission;
});
commands.Add(discordBackendCommand);
}
}
if (globalCommandsDeleteList.NotEmptyAndNotNull())
{
foreach (var cmdId in globalCommandsDeleteList)
{
try
{
await ApplicationCommandsExtension.ClientInternal.DeleteGlobalApplicationCommandAsync(cmdId);
}
catch (NotFoundException)
{
ApplicationCommandsExtension.ClientInternal.Logger.LogError($"Could not delete global command {cmdId}. Please clean up manually");
}
}
}
return commands.NotEmptyAndNotNull() ? commands : null;
}
///
/// Registers the guild commands.
///
/// The target guild id.
/// The command list.
/// A list of registered commands.
internal static async Task> RegisterGuilldCommandsAsync(ulong guildId, List commands)
{
var guildCommandsOverwriteList = BuildGuildOverwriteList(guildId, commands);
var guildCommandsCreateList = BuildGuildCreateList(guildId, commands);
var guildCommandsDeleteList = BuildGuildDeleteList(guildId, commands);
if (guildCommandsCreateList.NotEmptyAndNotNull() && guildCommandsOverwriteList.EmptyOrNull())
{
var cmds = await ApplicationCommandsExtension.ClientInternal.BulkOverwriteGuildApplicationCommandsAsync(guildId, guildCommandsCreateList);
commands.AddRange(cmds);
}
else if (guildCommandsCreateList.EmptyOrNull() && guildCommandsOverwriteList.NotEmptyAndNotNull())
{
List overwriteList = new();
foreach (var overwrite in guildCommandsOverwriteList)
{
var cmd = overwrite.Value;
cmd.Id = overwrite.Key;
overwriteList.Add(cmd);
}
var discordBackendCommands = await ApplicationCommandsExtension.ClientInternal.BulkOverwriteGuildApplicationCommandsAsync(guildId, overwriteList);
commands.AddRange(discordBackendCommands);
}
else if (guildCommandsCreateList.NotEmptyAndNotNull() && guildCommandsOverwriteList.NotEmptyAndNotNull())
{
foreach (var cmd in guildCommandsCreateList)
{
var discordBackendCommand = await ApplicationCommandsExtension.ClientInternal.CreateGuildApplicationCommandAsync(guildId, cmd);
commands.Add(discordBackendCommand);
}
foreach (var cmd in guildCommandsOverwriteList)
{
var command = cmd.Value;
var discordBackendCommand = await ApplicationCommandsExtension.ClientInternal.EditGuildApplicationCommandAsync(guildId, cmd.Key, action =>
{
action.Name = command.Name;
action.NameLocalizations = command.NameLocalizations;
action.Description = command.Description;
action.DescriptionLocalizations = command.DescriptionLocalizations;
if(command.Options != null && command.Options.Any())
action.Options = Entities.Optional.FromValue(command.Options);
action.DefaultPermission = command.DefaultPermission;
});
commands.Add(discordBackendCommand);
}
}
if (guildCommandsDeleteList.NotEmptyAndNotNull())
{
foreach (var cmdId in guildCommandsDeleteList)
{
try
{
await ApplicationCommandsExtension.ClientInternal.DeleteGuildApplicationCommandAsync(guildId, cmdId);
}
catch (NotFoundException)
{
ApplicationCommandsExtension.ClientInternal.Logger.LogError($"Could not delete guild command {cmdId} in guild {guildId}. Please clean up manually");
}
}
}
return commands.NotEmptyAndNotNull() ? commands : null;
}
///
/// Builds a list of guild command ids to be deleted on discords backend.
///
/// The guild id these commands belong to.
/// The command list.
/// A list of command ids.
private static List BuildGuildDeleteList(ulong guildId, List updateList)
{
List discord;
if (ApplicationCommandsExtension.GuildDiscordCommands == null || !ApplicationCommandsExtension.GuildDiscordCommands.Any()
|| !ApplicationCommandsExtension.GuildDiscordCommands.GetFirstValueByKey(guildId, out discord)
)
return null;
List invalidCommandIds = new();
if (updateList == null)
{
foreach (var cmd in discord)
{
invalidCommandIds.Add(cmd.Id);
}
}
else
{
foreach (var cmd in discord)
{
if (!updateList.Any(ul => ul.Name == cmd.Name))
invalidCommandIds.Add(cmd.Id);
}
}
return invalidCommandIds;
}
///
/// Builds a list of guild commands to be created on discords backend.
///
/// The guild id these commands belong to.
/// The command list.
///
private static List BuildGuildCreateList(ulong guildId, List updateList)
{
List discord;
if (ApplicationCommandsExtension.GuildDiscordCommands == null || !ApplicationCommandsExtension.GuildDiscordCommands.Any()
|| updateList == null || !ApplicationCommandsExtension.GuildDiscordCommands.GetFirstValueByKey(guildId, out discord)
)
return updateList;
List newCommands = new();
foreach (var cmd in updateList)
{
if (!discord.Any(d => d.Name == cmd.Name))
{
newCommands.Add(cmd);
}
}
return newCommands;
}
///
/// Builds a list of guild commands to be overwritten on discords backend.
///
/// The guild id these commands belong to.
/// The command list.
/// A dictionary of command id and command.
private static Dictionary BuildGuildOverwriteList(ulong guildId, List updateList)
{
List discord;
if (ApplicationCommandsExtension.GuildDiscordCommands == null || !ApplicationCommandsExtension.GuildDiscordCommands.Any()
- || !ApplicationCommandsExtension.GuildDiscordCommands.Any(l => l.Key == guildId) || updateList == null
+ || ApplicationCommandsExtension.GuildDiscordCommands.All(l => l.Key != guildId) || updateList == null
|| !ApplicationCommandsExtension.GuildDiscordCommands.GetFirstValueByKey(guildId, out discord)
)
return null;
Dictionary updateCommands = new();
foreach (var cmd in updateList)
{
if (discord.GetFirstValueWhere(d => d.Name == cmd.Name, out var command))
updateCommands.Add(command.Id, cmd);
}
return updateCommands;
}
///
/// Builds a list of global command ids to be deleted on discords backend.
///
/// The command list.
/// A list of command ids.
private static List BuildGlobalDeleteList(List updateList = null)
{
if (ApplicationCommandsExtension.GlobalDiscordCommands == null || !ApplicationCommandsExtension.GlobalDiscordCommands.Any()
|| ApplicationCommandsExtension.GlobalDiscordCommands == null
)
return null;
var discord = ApplicationCommandsExtension.GlobalDiscordCommands;
List invalidCommandIds = new();
if (updateList == null)
{
foreach (var cmd in discord)
{
invalidCommandIds.Add(cmd.Id);
}
}
else
{
foreach (var cmd in discord)
{
- if (!updateList.Any(ul => ul.Name == cmd.Name))
+ if (updateList.All(ul => ul.Name != cmd.Name))
invalidCommandIds.Add(cmd.Id);
}
}
return invalidCommandIds;
}
///
/// Builds a list of global commands to be created on discords backend.
///
/// The command list.
/// A list of commands.
private static List BuildGlobalCreateList(List updateList)
{
if (ApplicationCommandsExtension.GlobalDiscordCommands == null || !ApplicationCommandsExtension.GlobalDiscordCommands.Any() || updateList == null)
return updateList;
var discord = ApplicationCommandsExtension.GlobalDiscordCommands;
List newCommands = new();
foreach (var cmd in updateList)
{
if (discord.Any(d => d.Name == cmd.Name))
{
newCommands.Add(cmd);
}
}
return newCommands;
}
///
/// Builds a list of global commands to be overwritten on discords backend.
///
/// The command list.
/// A dictionary of command ids and commands.
private static Dictionary BuildGlobalOverwriteList(List updateList)
{
if (ApplicationCommandsExtension.GlobalDiscordCommands == null || !ApplicationCommandsExtension.GlobalDiscordCommands.Any()
|| updateList == null || ApplicationCommandsExtension.GlobalDiscordCommands == null
)
return null;
var discord = ApplicationCommandsExtension.GlobalDiscordCommands;
Dictionary updateCommands = new();
foreach (var cmd in updateList)
{
if (discord.GetFirstValueWhere(d => d.Name == cmd.Name, out var command))
updateCommands.Add(command.Id, cmd);
}
return updateCommands;
}
}
}