Ejemplo n.º 1
0
        private async Task <IResult> ExecuteAsync(IInteractionContext context, IEnumerable <SlashCommandParameterInfo> paramList,
                                                  List <IApplicationCommandInteractionDataOption> argList, IServiceProvider services)
        {
            try
            {
                if (paramList?.Count() < argList?.Count())
                {
                    return(ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command was invoked with too many parameters"));
                }

                var args = new object[paramList.Count()];

                for (var i = 0; i < paramList.Count(); i++)
                {
                    var parameter = paramList.ElementAt(i);

                    var arg = argList?.Find(x => string.Equals(x.Name, parameter.Name, StringComparison.OrdinalIgnoreCase));

                    if (arg == default)
                    {
                        if (parameter.IsRequired)
                        {
                            return(ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command was invoked with too few parameters"));
                        }
                        else
                        {
                            args[i] = parameter.DefaultValue;
                        }
                    }
                    else
                    {
                        var typeConverter = parameter.TypeConverter;

                        var readResult = await typeConverter.ReadAsync(context, arg, services).ConfigureAwait(false);

                        if (!readResult.IsSuccess)
                        {
                            await InvokeModuleEvent(context, readResult).ConfigureAwait(false);

                            return(readResult);
                        }

                        args[i] = readResult.Value;
                    }
                }

                return(await RunAsync(context, args, services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                return(ExecuteResult.FromError(ex));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Execute this command using dependency injection.
        /// </summary>
        /// <param name="context">Context that will be injected to the <see cref="InteractionModuleBase{T}"/>.</param>
        /// <param name="services">Services that will be used while initializing the <see cref="InteractionModuleBase{T}"/>.</param>
        /// <param name="additionalArgs">Provide additional string parameters to the method along with the auto generated parameters.</param>
        /// <returns>
        ///     A task representing the asynchronous command execution process.
        /// </returns>
        public async Task <IResult> ExecuteAsync(IInteractionContext context, IServiceProvider services, params string[] additionalArgs)
        {
            if (context.Interaction is not IModalInteraction modalInteraction)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Modal Interaction."));
            }

            try
            {
                var args         = new object[Parameters.Count];
                var captureCount = additionalArgs?.Length ?? 0;

                for (var i = 0; i < Parameters.Count; i++)
                {
                    var parameter = Parameters.ElementAt(i);

                    if (i < captureCount)
                    {
                        var readResult = await parameter.TypeReader.ReadAsync(context, additionalArgs[i], services).ConfigureAwait(false);

                        if (!readResult.IsSuccess)
                        {
                            return(await InvokeEventAndReturn(context, readResult).ConfigureAwait(false));
                        }

                        args[i] = readResult.Value;
                    }
                    else
                    {
                        var modalResult = await Modal.CreateModalAsync(context, services, Module.CommandService._exitOnMissingModalField).ConfigureAwait(false);

                        if (!modalResult.IsSuccess)
                        {
                            return(await InvokeEventAndReturn(context, modalResult).ConfigureAwait(false));
                        }

                        if (modalResult is not ParseResult parseResult)
                        {
                            return(await InvokeEventAndReturn(context, ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command parameter parsing failed for an unknown reason.")));
                        }

                        args[i] = parseResult.Value;
                    }
                }
                return(await RunAsync(context, args, services));
            }
            catch (Exception ex)
            {
                return(await InvokeEventAndReturn(context, ExecuteResult.FromError(ex)).ConfigureAwait(false));
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Execute this command using dependency injection.
        /// </summary>
        /// <param name="context">Context that will be injected to the <see cref="InteractionModuleBase{T}"/>.</param>
        /// <param name="services">Services that will be used while initializing the <see cref="InteractionModuleBase{T}"/>.</param>
        /// <param name="additionalArgs">Provide additional string parameters to the method along with the auto generated parameters.</param>
        /// <returns>
        ///     A task representing the asynchronous command execution process.
        /// </returns>
        public async Task<IResult> ExecuteAsync(IInteractionContext context, IServiceProvider services, params string[] additionalArgs)
        {
            if (context.Interaction is not IComponentInteraction componentInteraction)
                return ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Message Component Interaction");

            var args = new List<string>();

            if (additionalArgs is not null)
                args.AddRange(additionalArgs);

            if (componentInteraction.Data?.Values is not null)
                args.AddRange(componentInteraction.Data.Values);

            return await ExecuteAsync(context, Parameters, args, services);
        }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        public override async Task <IResult> ExecuteAsync(IInteractionContext context, IServiceProvider services)
        {
            if (context.Interaction is not ISlashCommandInteraction slashCommand)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Slash Command Interaction"));
            }

            var options = slashCommand.Data.Options;

            while (options != null && options.Any(x => x.Type == ApplicationCommandOptionType.SubCommand || x.Type == ApplicationCommandOptionType.SubCommandGroup))
            {
                options = options.ElementAt(0)?.Options;
            }

            return(await ExecuteAsync(context, Parameters, options?.ToList(), services));
        }
Ejemplo n.º 5
0
        /// <inheritdoc/>
        public override async Task <IResult> ExecuteAsync(IInteractionContext context, IServiceProvider services)
        {
            if (context.Interaction is not IAutocompleteInteraction)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Autocomplete Interaction"));
            }

            try
            {
                return(await RunAsync(context, Array.Empty <object>(), services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                return(ExecuteResult.FromError(ex));
            }
        }
Ejemplo n.º 6
0
        /// <inheritdoc/>
        public async Task <IResult> ExecuteAsync(IInteractionContext context, IEnumerable <CommandParameterInfo> paramList, IEnumerable <string> values,
                                                 IServiceProvider services)
        {
            if (context.Interaction is not SocketMessageComponent messageComponent)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Component Command Interaction"));
            }

            try
            {
                var strCount = Parameters.Count(x => x.ParameterType == typeof(string));

                if (strCount > values?.Count())
                {
                    return(ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command was invoked with too few parameters"));
                }

                var componentValues = messageComponent.Data?.Values;

                var args = new object[Parameters.Count];

                if (componentValues is not null)
                {
                    if (Parameters.Last().ParameterType == typeof(string[]))
                    {
                        args[args.Length - 1] = componentValues.ToArray();
                    }
                    else
                    {
                        return(ExecuteResult.FromError(InteractionCommandError.BadArgs, $"Select Menu Interaction handlers must accept a {typeof(string[]).FullName} as its last parameter"));
                    }
                }

                for (var i = 0; i < strCount; i++)
                {
                    args[i] = values.ElementAt(i);
                }

                return(await RunAsync(context, args, services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                return(ExecuteResult.FromError(ex));
            }
        }
Ejemplo n.º 7
0
        private async Task <IResult> ParseArgument(SlashCommandParameterInfo parameterInfo, IInteractionContext context, List <IApplicationCommandInteractionDataOption> argList,
                                                   IServiceProvider services)
        {
            if (parameterInfo.IsComplexParameter)
            {
                var ctorArgs = new object[parameterInfo.ComplexParameterFields.Count];

                for (var i = 0; i < ctorArgs.Length; i++)
                {
                    var result = await ParseArgument(parameterInfo.ComplexParameterFields.ElementAt(i), context, argList, services).ConfigureAwait(false);

                    if (!result.IsSuccess)
                    {
                        return(result);
                    }

                    if (result is not ParseResult parseResult)
                    {
                        return(ExecuteResult.FromError(InteractionCommandError.BadArgs, "Complex command parsing failed for an unknown reason."));
                    }

                    ctorArgs[i] = parseResult.Value;
                }

                return(ParseResult.FromSuccess(parameterInfo._complexParameterInitializer(ctorArgs)));
            }

            var arg = argList?.Find(x => string.Equals(x.Name, parameterInfo.Name, StringComparison.OrdinalIgnoreCase));

            if (arg == default)
            {
                return(parameterInfo.IsRequired ? ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command was invoked with too few parameters") :
                       ParseResult.FromSuccess(parameterInfo.DefaultValue));
            }

            var typeConverter = parameterInfo.TypeConverter;
            var readResult    = await typeConverter.ReadAsync(context, arg, services).ConfigureAwait(false);

            if (!readResult.IsSuccess)
            {
                return(readResult);
            }

            return(ParseResult.FromSuccess(readResult.Value));
        }
Ejemplo n.º 8
0
        /// <inheritdoc/>
        public async Task <IResult> ExecuteAsync(IInteractionContext context, IEnumerable <CommandParameterInfo> paramList, IEnumerable <string> wildcardCaptures, IComponentInteractionData data,
                                                 IServiceProvider services)
        {
            var paramCount   = paramList.Count();
            var captureCount = wildcardCaptures?.Count() ?? 0;

            if (context.Interaction is not IComponentInteraction messageComponent)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Component Command Interaction"));
            }

            try
            {
                var args = new object[paramCount];

                for (var i = 0; i < paramCount; i++)
                {
                    var parameter = Parameters.ElementAt(i);
                    var isCapture = i < captureCount;

                    if (isCapture ^ parameter.IsRouteSegmentParameter)
                    {
                        return(await InvokeEventAndReturn(context, ExecuteResult.FromError(InteractionCommandError.BadArgs, "Argument type and parameter type didn't match (Wild Card capture/Component value)")).ConfigureAwait(false));
                    }

                    var readResult = isCapture ? await parameter.TypeReader.ReadAsync(context, wildcardCaptures.ElementAt(i), services).ConfigureAwait(false) :
                                     await parameter.TypeConverter.ReadAsync(context, data, services).ConfigureAwait(false);

                    if (!readResult.IsSuccess)
                    {
                        return(await InvokeEventAndReturn(context, readResult).ConfigureAwait(false));
                    }

                    args[i] = readResult.Value;
                }

                return(await RunAsync(context, args, services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                return(await InvokeEventAndReturn(context, ExecuteResult.FromError(ex)).ConfigureAwait(false));
            }
        }
        /// <inheritdoc/>
        public override async Task <IResult> ExecuteAsync(IInteractionContext context, IServiceProvider services)
        {
            if (context.Interaction is not IMessageCommandInteraction messageCommand)
            {
                return(ExecuteResult.FromError(InteractionCommandError.ParseFailed, $"Provided {nameof(IInteractionContext)} doesn't belong to a Message Command Interation"));
            }

            try
            {
                object[] args = new object[1] {
                    messageCommand.Data.Message
                };

                return(await RunAsync(context, args, services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                return(ExecuteResult.FromError(ex));
            }
        }
Ejemplo n.º 10
0
        private async Task <IResult> ExecuteAsync(IInteractionContext context, IEnumerable <SlashCommandParameterInfo> paramList,
                                                  List <IApplicationCommandInteractionDataOption> argList, IServiceProvider services)
        {
            try
            {
                var args = new object[paramList.Count()];

                for (var i = 0; i < paramList.Count(); i++)
                {
                    var parameter = paramList.ElementAt(i);

                    var result = await ParseArgument(parameter, context, argList, services).ConfigureAwait(false);

                    if (!result.IsSuccess)
                    {
                        var execResult = ExecuteResult.FromError(result);
                        await InvokeModuleEvent(context, execResult).ConfigureAwait(false);

                        return(execResult);
                    }

                    if (result is ParseResult parseResult)
                    {
                        args[i] = parseResult.Value;
                    }
                    else
                    {
                        return(ExecuteResult.FromError(InteractionCommandError.BadArgs, "Command parameter parsing failed for an unknown reason."));
                    }
                }

                return(await RunAsync(context, args, services).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                var result = ExecuteResult.FromError(ex);
                await InvokeModuleEvent(context, result).ConfigureAwait(false);

                return(result);
            }
        }
Ejemplo n.º 11
0
        private async Task <IResult> ExecuteInternalAsync(IInteractionContext context, object[] args, IServiceProvider services)
        {
            await CommandService._cmdLogger.DebugAsync($"Executing {GetLogString(context)}").ConfigureAwait(false);

            try
            {
                var preconditionResult = await CheckPreconditionsAsync(context, services).ConfigureAwait(false);

                if (!preconditionResult.IsSuccess)
                {
                    await InvokeModuleEvent(context, preconditionResult).ConfigureAwait(false);

                    return(preconditionResult);
                }

                var index = 0;
                foreach (var parameter in Parameters)
                {
                    var result = await parameter.CheckPreconditionsAsync(context, args[index++], services).ConfigureAwait(false);

                    if (!result.IsSuccess)
                    {
                        await InvokeModuleEvent(context, result).ConfigureAwait(false);

                        return(result);
                    }
                }

                var task = _action(context, args, services, this);

                if (task is Task <IResult> resultTask)
                {
                    var result = await resultTask.ConfigureAwait(false);
                    await InvokeModuleEvent(context, result).ConfigureAwait(false);

                    if (result is RuntimeResult || result is ExecuteResult)
                    {
                        return(result);
                    }
                }
                else
                {
                    await task.ConfigureAwait(false);

                    var result = ExecuteResult.FromSuccess();
                    await InvokeModuleEvent(context, result).ConfigureAwait(false);

                    return(result);
                }

                var failResult = ExecuteResult.FromError(InteractionCommandError.Unsuccessful, "Command execution failed for an unknown reason");
                await InvokeModuleEvent(context, failResult).ConfigureAwait(false);

                return(failResult);
            }
            catch (Exception ex)
            {
                var originalEx = ex;
                while (ex is TargetInvocationException)
                {
                    ex = ex.InnerException;
                }

                await Module.CommandService._cmdLogger.ErrorAsync(ex).ConfigureAwait(false);

                var result = ExecuteResult.FromError(ex);
                await InvokeModuleEvent(context, result).ConfigureAwait(false);

                if (Module.CommandService._throwOnError)
                {
                    if (ex == originalEx)
                    {
                        throw;
                    }
                    else
                    {
                        ExceptionDispatchInfo.Capture(ex).Throw();
                    }
                }

                return(result);
            }
            finally
            {
                await CommandService._cmdLogger.VerboseAsync($"Executed {GetLogString(context)}").ConfigureAwait(false);
            }
        }