GroupCommandsIncludeGroupCommand ( GroupCommands groupCommands, GroupCommands groupCommand ) { return((groupCommands & groupCommand) != 0); }
//************************************************************************* // Constructor: RunGroupCommandEventArgs() // /// <summary> /// Initializes a new instance of the <see /// cref="RunGroupCommandEventArgs" /> class. /// </summary> /// /// <param name="groupCommand"> /// The single group command that needs to be run. /// </param> /// /// <remarks> /// Note that although <see cref="GroupCommands" /> flags can be ORed /// together, the <paramref name="groupCommand" /> argument should include /// only one of these flags. /// </remarks> //************************************************************************* public RunGroupCommandEventArgs ( GroupCommands groupCommand ) { m_eGroupCommand = groupCommand; AssertValid(); }
protected override void ApplicationStartup(ILifetimeScope container, IPipelines pipelines) { ClashCaller.Init(); Bots.Init(); GroupCommands.Init(); Mods.Init(); try { //The bot can live if the members consistency isn't verified. Members.UpdateMembersByGroup(ConfigurationManager.AppSettings["GROUPME_TOKEN"], ConfigurationManager.AppSettings["GENERALCHAT_ID"]); Members.UpdateMembersByGroup(ConfigurationManager.AppSettings["GROUPME_TOKEN"], ConfigurationManager.AppSettings["WARCHAT_ID"]); } catch (Exception ex) { Bots.TestChatBot.SendMessage("Error while saving members into the database"); Bots.TestChatBot.SendMessage(ex.ToString()); } base.ApplicationStartup(container, pipelines); }
GetGroupCommandsToEnableInternal ( Microsoft.Office.Interop.Excel.Workbook oWorkbook ) { Debug.Assert(oWorkbook != null); GroupCommands eGroupCommandsToEnable = GroupCommands.None; ListObject oGroupTable; Range oSelectedTableRange; // Are any groups selected in the group table? if (ExcelTableUtil.TryGetSelectedTableRange(oWorkbook, WorksheetNames.Groups, TableNames.Groups, out oGroupTable, out oSelectedTableRange)) { // Yes. eGroupCommandsToEnable |= ( GroupCommands.CollapseSelectedGroups | GroupCommands.ExpandSelectedGroups | GroupCommands.RemoveSelectedGroups ); } // Are any vertices selected in the vertex table? ListObject oVertexTable; Boolean bVerticesSelected = ExcelTableUtil.TryGetSelectedTableRange( oWorkbook, WorksheetNames.Vertices, TableNames.Vertices, out oVertexTable, out oSelectedTableRange); if (bVerticesSelected) { eGroupCommandsToEnable |= GroupCommands.AddSelectedVerticesToGroup; } // Are there any groups? if (!ExcelTableUtil.VisibleTableRangeIsEmpty(oGroupTable)) { // Yes. eGroupCommandsToEnable |= ( GroupCommands.CollapseAllGroups | GroupCommands.ExpandAllGroups | GroupCommands.SelectAllGroups | GroupCommands.RemoveAllGroups ); if (bVerticesSelected) { eGroupCommandsToEnable |= ( GroupCommands.SelectGroupsWithSelectedVertices | GroupCommands.RemoveSelectedVerticesFromGroups ); } } return(eGroupCommandsToEnable); }
TryRunGroupCommand ( GroupCommands groupCommand, Microsoft.Office.Interop.Excel.Workbook workbook, Sheet2 vertexWorksheet, Sheet5 groupWorksheet ) { Debug.Assert(workbook != null); Debug.Assert(vertexWorksheet != null); Debug.Assert(groupWorksheet != null); switch (groupCommand) { case GroupCommands.None: return(true); case GroupCommands.CollapseSelectedGroups: return(TryCollapseOrExpandSelectedGroups(workbook, true)); case GroupCommands.ExpandSelectedGroups: return(TryCollapseOrExpandSelectedGroups(workbook, false)); case GroupCommands.CollapseAllGroups: return(TryCollapseOrExpandAllGroups(workbook, true)); case GroupCommands.ExpandAllGroups: return(TryCollapseOrExpandAllGroups(workbook, false)); case GroupCommands.SelectGroupsWithSelectedVertices: return(TrySelectGroupsWithSelectedVertices(workbook, vertexWorksheet, groupWorksheet)); case GroupCommands.SelectAllGroups: return(TrySelectAllGroups(workbook)); case GroupCommands.AddSelectedVerticesToGroup: return(TryAddSelectedVerticesToGroup(workbook, vertexWorksheet)); case GroupCommands.RemoveSelectedVerticesFromGroups: ICollection <String> oSelectedVertexNames; return(TryRemoveSelectedVerticesFromGroups(workbook, vertexWorksheet, out oSelectedVertexNames)); case GroupCommands.RemoveSelectedGroups: return(TryRemoveSelectedGroups(workbook, groupWorksheet)); case GroupCommands.RemoveAllGroups: return(TryRemoveAllGroups(workbook)); default: Debug.Assert(false); return(false); } }
private void RegisterCommands(Type t, ulong?guildid) { CommandMethod[] InternalCommandMethods = Array.Empty <CommandMethod>(); GroupCommand[] InternalGroupCommands = Array.Empty <GroupCommand>(); SubGroupCommand[] InternalSubGroupCommands = Array.Empty <SubGroupCommand>(); Client.Ready += (s, e) => { _ = Task.Run(async() => { try { List <CommandCreatePayload> ToUpdate = new List <CommandCreatePayload>(); var ti = t.GetTypeInfo(); var classes = ti.DeclaredNestedTypes; foreach (var tti in classes.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null)) { var groupatt = tti.GetCustomAttribute <SlashCommandGroupAttribute>(); var submethods = tti.DeclaredMethods; var subclasses = tti.DeclaredNestedTypes; if (subclasses.Any(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null) && submethods.Any(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { throw new ArgumentException("Slash command groups cannot have both subcommands and subgroups!"); } var payload = new CommandCreatePayload { Name = groupatt.Name, Description = groupatt.Description }; var commandmethods = new Dictionary <string, MethodInfo>(); foreach (var submethod in submethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { var commandattribute = submethod.GetCustomAttribute <SlashCommandAttribute>(); var subpayload = new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description); var parameters = submethod.GetParameters(); if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext))) { throw new ArgumentException($"The first argument must be an InteractionContext!"); } parameters = parameters.Skip(1).ToArray(); foreach (var parameter in parameters) { var optionattribute = parameter.GetCustomAttribute <OptionAttribute>(); if (optionattribute == null) { throw new ArgumentException("Arguments must have the Option attribute!"); } var type = parameter.ParameterType; ApplicationCommandOptionType parametertype; if (ReferenceEquals(type, typeof(string))) { parametertype = ApplicationCommandOptionType.String; } else if (ReferenceEquals(type, typeof(long))) { parametertype = ApplicationCommandOptionType.Integer; } else if (ReferenceEquals(type, typeof(bool))) { parametertype = ApplicationCommandOptionType.Boolean; } else if (ReferenceEquals(type, typeof(DiscordChannel))) { parametertype = ApplicationCommandOptionType.Channel; } else if (ReferenceEquals(type, typeof(DiscordUser))) { parametertype = ApplicationCommandOptionType.User; } else if (ReferenceEquals(type, typeof(DiscordRole))) { parametertype = ApplicationCommandOptionType.Role; } else { throw new ArgumentException("Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole."); } DiscordApplicationCommandOptionChoice[] choices = null; var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>(); if (choiceattributes.Any()) { choices = Array.Empty <DiscordApplicationCommandOptionChoice>(); foreach (var att in choiceattributes) { choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray(); } } var list = subpayload.Options?.ToList() ?? new List <DiscordApplicationCommandOption>(); list.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description) { Required = !parameter.IsOptional, Type = parametertype, Choices = choices }); subpayload.Options = list; } commandmethods.Add(commandattribute.Name, submethod); payload.Options.Add(new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description) { Required = null, Options = subpayload.Options, Type = ApplicationCommandOptionType.SubCommand }); InternalGroupCommands = InternalGroupCommands.Append(new GroupCommand { Name = groupatt.Name, ParentClass = tti, Methods = commandmethods }).ToArray(); } foreach (var subclass in subclasses.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null)) { var subgroupatt = subclass.GetCustomAttribute <SlashCommandGroupAttribute>(); var subsubmethods = subclass.DeclaredMethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null); var command = new SubGroupCommand { Name = groupatt.Name }; var subpayload = new DiscordApplicationCommandOption(subgroupatt.Name, subgroupatt.Description) { Required = null, Type = ApplicationCommandOptionType.SubCommandGroup, Options = new List <DiscordApplicationCommandOption>() }; foreach (var subsubmethod in subsubmethods) { var commatt = subsubmethod.GetCustomAttribute <SlashCommandAttribute>(); var subsubpayload = new DiscordApplicationCommandOption(commatt.Name, commatt.Description) { Type = ApplicationCommandOptionType.SubCommand, }; var parameters = subsubmethod.GetParameters(); if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext))) { throw new ArgumentException($"The first argument must be an InteractionContext!"); } parameters = parameters.Skip(1).ToArray(); foreach (var parameter in parameters) { var optionattribute = parameter.GetCustomAttribute <OptionAttribute>(); if (optionattribute == null) { throw new ArgumentException("Arguments must have the Option attribute!"); } var type = parameter.ParameterType; ApplicationCommandOptionType parametertype; if (ReferenceEquals(type, typeof(string))) { parametertype = ApplicationCommandOptionType.String; } else if (ReferenceEquals(type, typeof(long))) { parametertype = ApplicationCommandOptionType.Integer; } else if (ReferenceEquals(type, typeof(bool))) { parametertype = ApplicationCommandOptionType.Boolean; } else if (ReferenceEquals(type, typeof(DiscordChannel))) { parametertype = ApplicationCommandOptionType.Channel; } else if (ReferenceEquals(type, typeof(DiscordUser))) { parametertype = ApplicationCommandOptionType.User; } else if (ReferenceEquals(type, typeof(DiscordRole))) { parametertype = ApplicationCommandOptionType.Role; } else { throw new ArgumentException("Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole."); } DiscordApplicationCommandOptionChoice[] choices = null; var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>(); if (choiceattributes.Any()) { choices = Array.Empty <DiscordApplicationCommandOptionChoice>(); foreach (var att in choiceattributes) { choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray(); } } var list = subsubpayload.Options?.ToList() ?? new List <DiscordApplicationCommandOption>(); list.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description) { Required = !parameter.IsOptional, Type = parametertype, Choices = choices }); subsubpayload.Options = list; } subpayload.Options = subpayload.Options.ToArray().Append(subsubpayload).ToList(); commandmethods.Add(commatt.Name, subsubmethod); } command.SubCommands.Add(new GroupCommand { Name = subgroupatt.Name, ParentClass = subclass, Methods = commandmethods }); InternalSubGroupCommands = InternalSubGroupCommands.Append(command).ToArray(); payload.Options.Add(subpayload); } ToUpdate.Add(payload); } var methods = ti.DeclaredMethods; foreach (var method in methods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { var commandattribute = method.GetCustomAttribute <SlashCommandAttribute>(); var payload = new CommandCreatePayload { Name = commandattribute.Name, Description = commandattribute.Description }; var parameters = method.GetParameters(); if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext))) { throw new ArgumentException($"The first argument must be an InteractionContext!"); } parameters = parameters.Skip(1).ToArray(); foreach (var parameter in parameters) { var optionattribute = parameter.GetCustomAttribute <OptionAttribute>(); if (optionattribute == null) { throw new ArgumentException("Arguments must have the SlashOption attribute!"); } var type = parameter.ParameterType; ApplicationCommandOptionType parametertype; if (ReferenceEquals(type, typeof(string))) { parametertype = ApplicationCommandOptionType.String; } else if (ReferenceEquals(type, typeof(long))) { parametertype = ApplicationCommandOptionType.Integer; } else if (ReferenceEquals(type, typeof(bool))) { parametertype = ApplicationCommandOptionType.Boolean; } else if (ReferenceEquals(type, typeof(DiscordChannel))) { parametertype = ApplicationCommandOptionType.Channel; } else if (ReferenceEquals(type, typeof(DiscordUser))) { parametertype = ApplicationCommandOptionType.User; } else if (ReferenceEquals(type, typeof(DiscordRole))) { parametertype = ApplicationCommandOptionType.Role; } else { throw new ArgumentException($"Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole."); } DiscordApplicationCommandOptionChoice[] choices = null; var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>(); if (choiceattributes.Any()) { choices = Array.Empty <DiscordApplicationCommandOptionChoice>(); foreach (var att in choiceattributes) { choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray(); } } payload.Options.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description) { Required = !parameter.IsOptional, Type = parametertype, Choices = choices }); } InternalCommandMethods = InternalCommandMethods.Append(new CommandMethod { Method = method, Name = commandattribute.Name, ParentClass = t }).ToArray(); ToUpdate.Add(payload); } var commands = await BulkCreateCommandsAsync(ToUpdate, guildid); foreach (var command in commands) { if (InternalCommandMethods.Any(x => x.Name == command.Name)) { InternalCommandMethods.First(x => x.Name == command.Name).Id = command.Id; } else if (InternalGroupCommands.Any(x => x.Name == command.Name)) { InternalGroupCommands.First(x => x.Name == command.Name).Id = command.Id; } else if (InternalSubGroupCommands.Any(x => x.Name == command.Name)) { InternalSubGroupCommands.First(x => x.Name == command.Name).Id = command.Id; } } CommandMethods.AddRange(InternalCommandMethods); GroupCommands.AddRange(InternalGroupCommands); SubGroupCommands.AddRange(InternalSubGroupCommands); } catch (Exception ex) { Client.Logger.LogError(ex, $"There was an error registering slash commands"); Environment.Exit(-1); } }); return(Task.CompletedTask); }; }
//Handler internal Task InteractionHandler(DiscordClient client, InteractionCreateEventArgs e) { _ = Task.Run(async() => { InteractionContext context = new InteractionContext { Interaction = e.Interaction, Channel = e.Interaction.Channel, Guild = e.Interaction.Guild, User = e.Interaction.User, Client = client, SlashCommandsExtension = this, CommandName = e.Interaction.Data.Name, InteractionId = e.Interaction.Id, Token = e.Interaction.Token }; try { var methods = CommandMethods.Where(x => x.Id == e.Interaction.Data.Id); var groups = GroupCommands.Where(x => x.Id == e.Interaction.Data.Id); var subgroups = SubGroupCommands.Where(x => x.Id == e.Interaction.Data.Id); if (!methods.Any() && !groups.Any() && !subgroups.Any()) { throw new SlashCommandNotFoundException("An interaction was created, but no command was registered for it"); } if (methods.Any()) { var method = methods.First(); List <object> args = new List <object> { context }; var parameters = method.Method.GetParameters().Skip(1); for (int i = 0; i < parameters.Count(); i++) { var parameter = parameters.ElementAt(i); if (parameter.IsOptional && (e.Interaction.Data.Options == null || e.Interaction.Data.Options?.ElementAtOrDefault(i) == default)) { args.Add(parameter.DefaultValue); } else { var option = e.Interaction.Data.Options.ElementAt(i); if (ReferenceEquals(parameter.ParameterType, typeof(string))) { args.Add(option.Value.ToString()); } else if (ReferenceEquals(parameter.ParameterType, typeof(long))) { args.Add((long)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(bool))) { args.Add((bool)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser))) { if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member)) { args.Add(member); } else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user)) { args.Add(user); } else { args.Add(await Client.GetUserAsync((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel))) { if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel)) { args.Add(channel); } else { args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole))) { if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role)) { args.Add(role); } else { args.Add(e.Interaction.Guild.GetRole((ulong)option.Value)); } } else { throw new ArgumentException($"How on earth did that happen"); } } } var classinstance = Activator.CreateInstance(method.ParentClass); var task = (Task)method.Method.Invoke(classinstance, args.ToArray()); await task; } else if (groups.Any()) { var command = e.Interaction.Data.Options.First(); var method = groups.First().Methods.First(x => x.Key == command.Name).Value; List <object> args = new List <object> { context }; var parameters = method.GetParameters().Skip(1); for (int i = 0; i < parameters.Count(); i++) { var parameter = parameters.ElementAt(i); if (parameter.IsOptional && (command.Options == null || command.Options?.ElementAtOrDefault(i) == default)) { args.Add(parameter.DefaultValue); } else { var option = command.Options.ElementAt(i); if (ReferenceEquals(parameter.ParameterType, typeof(string))) { args.Add(option.Value.ToString()); } else if (ReferenceEquals(parameter.ParameterType, typeof(long))) { args.Add((long)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(bool))) { args.Add((bool)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser))) { if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member)) { args.Add(member); } else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user)) { args.Add(user); } else { args.Add(await Client.GetUserAsync((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel))) { if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel)) { args.Add(channel); } else { args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole))) { if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role)) { args.Add(role); } else { args.Add(e.Interaction.Guild.GetRole((ulong)option.Value)); } } else { throw new ArgumentException($"How on earth did that happen"); } } } var classinstance = Activator.CreateInstance(groups.First().ParentClass); var task = (Task)method.Invoke(classinstance, args.ToArray()); await task; } else if (subgroups.Any()) { var command = e.Interaction.Data.Options.First(); var group = subgroups.First(x => x.SubCommands.Any(y => y.Name == command.Name)).SubCommands.First(x => x.Name == command.Name); var method = group.Methods.First(x => x.Key == command.Options.First().Name).Value; List <object> args = new List <object> { context }; var parameters = method.GetParameters().Skip(1); for (int i = 0; i < parameters.Count(); i++) { var parameter = parameters.ElementAt(i); if (parameter.IsOptional && (command.Options == null || command.Options?.ElementAtOrDefault(i) == default)) { args.Add(parameter.DefaultValue); } else { var option = command.Options.ElementAt(i); if (ReferenceEquals(parameter.ParameterType, typeof(string))) { args.Add(option.Value.ToString()); } else if (ReferenceEquals(parameter.ParameterType, typeof(long))) { args.Add((long)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(bool))) { args.Add((bool)option.Value); } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser))) { if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member)) { args.Add(member); } else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user)) { args.Add(user); } else { args.Add(await Client.GetUserAsync((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel))) { if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel)) { args.Add(channel); } else { args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value)); } } else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole))) { if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role)) { args.Add(role); } else { args.Add(e.Interaction.Guild.GetRole((ulong)option.Value)); } } else { throw new ArgumentException($"How on earth did that happen"); } } } var classinstance = Activator.CreateInstance(group.ParentClass); var task = (Task)method.Invoke(classinstance, args.ToArray()); await task; } await _executed.InvokeAsync(this, new SlashCommandExecutedEventArgs { Context = context }); } catch (Exception ex) { await _error.InvokeAsync(this, new SlashCommandErrorEventArgs { Context = context, Exception = ex }); } }); return(Task.CompletedTask); }
private void RegisterCommands(Type[] types, ulong?guildid) { CommandMethod[] InternalCommandMethods = Array.Empty <CommandMethod>(); GroupCommand[] InternalGroupCommands = Array.Empty <GroupCommand>(); SubGroupCommand[] InternalSubGroupCommands = Array.Empty <SubGroupCommand>(); List <DiscordApplicationCommand> ToUpdate = new List <DiscordApplicationCommand>(); _ = Task.Run(async() => { foreach (var t in types) { try { var ti = t.GetTypeInfo(); var classes = ti.DeclaredNestedTypes; foreach (var tti in classes.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null)) { var groupatt = tti.GetCustomAttribute <SlashCommandGroupAttribute>(); var submethods = tti.DeclaredMethods; var subclasses = tti.DeclaredNestedTypes; if (subclasses.Any(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null) && submethods.Any(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { throw new ArgumentException("Slash command groups cannot have both subcommands and subgroups!"); } var payload = new DiscordApplicationCommand(groupatt.Name, groupatt.Description); var commandmethods = new Dictionary <string, MethodInfo>(); foreach (var submethod in submethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { var commandattribute = submethod.GetCustomAttribute <SlashCommandAttribute>(); var parameters = submethod.GetParameters(); if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext))) { throw new ArgumentException($"The first argument must be an InteractionContext!"); } parameters = parameters.Skip(1).ToArray(); var options = ParseParameters(parameters); var subpayload = new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description, ApplicationCommandOptionType.SubCommand, null, null, options); commandmethods.Add(commandattribute.Name, submethod); payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options != null ? payload.Options.ToArray().Append(subpayload) : new DiscordApplicationCommandOption[] { subpayload }); InternalGroupCommands = InternalGroupCommands.Append(new GroupCommand { Name = groupatt.Name, ParentClass = tti, Methods = commandmethods }).ToArray(); } foreach (var subclass in subclasses.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null)) { var subgroupatt = subclass.GetCustomAttribute <SlashCommandGroupAttribute>(); var subsubmethods = subclass.DeclaredMethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null); var command = new SubGroupCommand { Name = groupatt.Name }; var options = new List <DiscordApplicationCommandOption>(); foreach (var subsubmethod in subsubmethods) { var suboptions = new List <DiscordApplicationCommandOption>(); var commatt = subsubmethod.GetCustomAttribute <SlashCommandAttribute>(); var parameters = subsubmethod.GetParameters(); if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext))) { throw new ArgumentException($"The first argument must be an InteractionContext!"); } parameters = parameters.Skip(1).ToArray(); options = options.Concat(ParseParameters(parameters)).ToList(); var subsubpayload = new DiscordApplicationCommandOption(commatt.Name, commatt.Description, ApplicationCommandOptionType.SubCommand, null, null, suboptions); options.Add(subsubpayload); commandmethods.Add(commatt.Name, subsubmethod); } var subpayload = new DiscordApplicationCommandOption(subgroupatt.Name, subgroupatt.Description, ApplicationCommandOptionType.SubCommandGroup, null, null, options); command.SubCommands.Add(new GroupCommand { Name = subgroupatt.Name, ParentClass = subclass, Methods = commandmethods }); InternalSubGroupCommands = InternalSubGroupCommands.Append(command).ToArray(); payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options != null ? payload.Options.ToArray().Append(subpayload) : new DiscordApplicationCommandOption[] { subpayload }); } ToUpdate.Add(payload); } var methods = ti.DeclaredMethods; foreach (var method in methods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null)) { var commandattribute = method.GetCustomAttribute <SlashCommandAttribute>(); var options = new List <DiscordApplicationCommandOption>(); 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(); foreach (var parameter in parameters) { var optionattribute = parameter.GetCustomAttribute <OptionAttribute>(); if (optionattribute == null) { throw new ArgumentException("Arguments must have the SlashOption attribute!"); } var type = parameter.ParameterType; ApplicationCommandOptionType parametertype = GetParameterType(type); DiscordApplicationCommandOptionChoice[] choices = GetChoiceAttributesFromParameter(parameter.GetCustomAttributes <ChoiceAttribute>()); options.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description, parametertype, !parameter.IsOptional, choices)); } InternalCommandMethods = InternalCommandMethods.Append(new CommandMethod { Method = method, Name = commandattribute.Name, ParentClass = t }).ToArray(); var payload = new DiscordApplicationCommand(commandattribute.Name, commandattribute.Description, options); ToUpdate.Add(payload); } } catch (Exception ex) { Client.Logger.LogError(ex, $"There was an error registering slash commands"); Environment.Exit(-1); } } try { IEnumerable <DiscordApplicationCommand> commands; if (guildid == null) { commands = await Client.BulkOverwriteGlobalApplicationCommandsAsync(ToUpdate); } else { commands = await Client.BulkOverwriteGuildApplicationCommandsAsync(guildid.Value, ToUpdate); } foreach (var command in commands) { if (InternalCommandMethods.Any(x => x.Name == command.Name)) { InternalCommandMethods.First(x => x.Name == command.Name).Id = command.Id; } else if (InternalGroupCommands.Any(x => x.Name == command.Name)) { InternalGroupCommands.First(x => x.Name == command.Name).Id = command.Id; } else if (InternalSubGroupCommands.Any(x => x.Name == command.Name)) { InternalSubGroupCommands.First(x => x.Name == command.Name).Id = command.Id; } } CommandMethods.AddRange(InternalCommandMethods); GroupCommands.AddRange(InternalGroupCommands); SubGroupCommands.AddRange(InternalSubGroupCommands); } catch (Exception ex) { Client.Logger.LogError(ex, $"There was an error registering slash commands"); Environment.Exit(-1); } }); }
//Handler private Task InteractionHandler(DiscordClient client, InteractionCreateEventArgs e) { _ = Task.Run(async() => { InteractionContext context = new InteractionContext { Interaction = e.Interaction, Channel = e.Interaction.Channel, Guild = e.Interaction.Guild, User = e.Interaction.User, Client = client, SlashCommandsExtension = this, CommandName = e.Interaction.Data.Name, InteractionId = e.Interaction.Id, Token = e.Interaction.Token, Services = _configuration?.Services }; try { var methods = CommandMethods.Where(x => x.Id == e.Interaction.Data.Id); var groups = GroupCommands.Where(x => x.Id == e.Interaction.Data.Id); var subgroups = SubGroupCommands.Where(x => x.Id == e.Interaction.Data.Id); if (!methods.Any() && !groups.Any() && !subgroups.Any()) { throw new Exception("An interaction was created, but no command was registered for it"); } if (methods.Any()) { var method = methods.First(); var args = await ResloveInteractionCommandParameters(e, context, method.Method); var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, method.ParentClass); var task = (Task)method.Method.Invoke(classinstance, args.ToArray()); await task; } else if (groups.Any()) { var command = e.Interaction.Data.Options.First(); var method = groups.First().Methods.First(x => x.Key == command.Name).Value; var args = await ResloveInteractionCommandParameters(e, context, method); var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, groups.First().ParentClass); var task = (Task)method.Invoke(classinstance, args.ToArray()); await task; } else if (subgroups.Any()) { var command = e.Interaction.Data.Options.First(); var group = subgroups.First(x => x.SubCommands.Any(y => y.Name == command.Name)).SubCommands.First(x => x.Name == command.Name); var method = group.Methods.First(x => x.Key == command.Options.First().Name).Value; var args = await ResloveInteractionCommandParameters(e, context, method); var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, group.ParentClass); var task = (Task)method.Invoke(classinstance, args.ToArray()); await task; } await _executed.InvokeAsync(this, new SlashCommandExecutedEventArgs { Context = context }); } catch (Exception ex) { await _error.InvokeAsync(this, new SlashCommandErrorEventArgs { Context = context, Exception = ex }); } }); return(Task.CompletedTask); }
//************************************************************************* // Method: TryRunGroupCommand() // /// <summary> /// Attempts to run a group command. /// </summary> /// /// <param name="groupCommand"> /// One of the flags in the <see cref="GroupCommands" /> enumeration. /// </param> /// /// <param name="workbook"> /// NodeXL workbook. /// </param> /// /// <param name="vertexWorksheet"> /// The vertex worksheet in the NodeXL workbook. /// </param> /// /// <param name="groupWorksheet"> /// The group worksheet in the NodeXL workbook. /// </param> /// /// <returns> /// true if successful. /// </returns> /// /// <remarks> /// This method may modify the contents of the workbook. It does not /// interact with the TaskPane, which contains the graph created from the /// workbook. It is the responsibility of the caller to communicate /// group changes to the TaskPane when necessary. /// /// <para> /// This method activates various worksheets to read their selection and /// write their contents. It is the responsibility of the caller to save /// the active worksheet state before calling this method and restore it /// afterward. /// </para> /// /// </remarks> //************************************************************************* public static Boolean TryRunGroupCommand( GroupCommands groupCommand, Microsoft.Office.Interop.Excel.Workbook workbook, Sheet2 vertexWorksheet, Sheet5 groupWorksheet ) { Debug.Assert(workbook != null); Debug.Assert(vertexWorksheet != null); Debug.Assert(groupWorksheet != null); switch (groupCommand) { case GroupCommands.None: return (true); case GroupCommands.CollapseSelectedGroups: return ( TryCollapseOrExpandSelectedGroups(workbook, true) ); case GroupCommands.ExpandSelectedGroups: return ( TryCollapseOrExpandSelectedGroups(workbook, false) ); case GroupCommands.CollapseAllGroups: return ( TryCollapseOrExpandAllGroups(workbook, true) ); case GroupCommands.ExpandAllGroups: return ( TryCollapseOrExpandAllGroups(workbook, false) ); case GroupCommands.SelectGroupsWithSelectedVertices: return ( TrySelectGroupsWithSelectedVertices(workbook, vertexWorksheet, groupWorksheet) ); case GroupCommands.SelectAllGroups: return ( TrySelectAllGroups(workbook) ); case GroupCommands.AddSelectedVerticesToGroup: return ( TryAddSelectedVerticesToGroup(workbook, vertexWorksheet) ); case GroupCommands.RemoveSelectedVerticesFromGroups: ICollection<String> oSelectedVertexNames; return ( TryRemoveSelectedVerticesFromGroups(workbook, vertexWorksheet, out oSelectedVertexNames) ); case GroupCommands.RemoveSelectedGroups: return ( TryRemoveSelectedGroups(workbook, groupWorksheet) ); case GroupCommands.RemoveAllGroups: return ( TryRemoveAllGroups(workbook) ); default: Debug.Assert(false); return (false); } }
GroupCommandsIncludeGroupCommand ( GroupCommands groupCommands, GroupCommands groupCommand ) { return ( (groupCommands & groupCommand) != 0 ); }
//************************************************************************* // Method: RunGroupCommand() // /// <summary> /// Runs a group command. /// </summary> /// /// <param name="groupCommand"> /// One of the flags in the <see cref="GroupCommands" /> enumeration. /// </param> //************************************************************************* public void RunGroupCommand( GroupCommands groupCommand ) { AssertValid(); if ( !this.ExcelApplicationIsReady(true) ) { return; } // Various worksheets must be activated for reading and writing. Save // the active worksheet state. ExcelActiveWorksheetRestorer oExcelActiveWorksheetRestorer = new ExcelActiveWorksheetRestorer(this.InnerObject); ExcelActiveWorksheetState oExcelActiveWorksheetState = oExcelActiveWorksheetRestorer.GetActiveWorksheetState(); try { if ( !GroupManager.TryRunGroupCommand(groupCommand, this.InnerObject, Globals.Sheet2, Globals.Sheet5) ) { return; } switch (groupCommand) { case GroupCommands.CollapseSelectedGroups: case GroupCommands.ExpandSelectedGroups: // Let the TaskPane know about the collapsed or expanded // groups. FireCollapseOrExpandGroups( groupCommand == GroupCommands.CollapseSelectedGroups, Globals.Sheet5.GetSelectedGroupNames() ); break; case GroupCommands.CollapseAllGroups: case GroupCommands.ExpandAllGroups: ICollection<String> oUniqueGroupNames; if ( ExcelUtil.TryGetUniqueTableColumnStringValues( this.InnerObject, WorksheetNames.Groups, TableNames.Groups, GroupTableColumnNames.Name, out oUniqueGroupNames) ) { FireCollapseOrExpandGroups( groupCommand == GroupCommands.CollapseAllGroups, oUniqueGroupNames); } break; default: break; } } catch (Exception oException) { ErrorUtil.OnException(oException); } finally { oExcelActiveWorksheetRestorer.Restore(oExcelActiveWorksheetState); } }