public Task <ExecuteCommandResult> ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteCommand(context, context.Message.Content.Substring(argPos), dependencyMap, multiMatchHandling);
public async Task <ExecuteCommandResult> ExecuteCommand(CommandContext context, string input, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { dependencyMap = dependencyMap ?? DependencyMap.Empty; var searchResult = _commandService.Search(context, input); if (!searchResult.IsSuccess) { return(new ExecuteCommandResult(null, null, searchResult)); } var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { var preconditionResult = await commands[i].CheckPreconditionsAsync(context).ConfigureAwait(false); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(new ExecuteCommandResult(null, null, preconditionResult)); } else { continue; } } var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { TypeReaderValue[] argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(new ExecuteCommandResult(null, null, parseResult)); } else { continue; } } } var cmd = commands[i].Command; bool resetCommand = cmd.Name == "resetperms"; var module = cmd.Module.GetTopLevelModule(); PermissionCache pc; if (context.Guild != null) { pc = Permissions.Cache.GetOrAdd(context.Guild.Id, (id) => { using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.PermissionsFor(context.Guild.Id); return(new PermissionCache() { Verbose = config.VerbosePermissions, RootPermission = config.RootPermission, PermRole = config.PermissionRole.Trim().ToLowerInvariant(), }); } }); int index; if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(context.Message, cmd.Aliases.First(), module.Name, out index)) { var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand((SocketGuild)context.Guild)}** is preventing this action."; return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg))); } if (module.Name == typeof(Permissions).Name) { var guildUser = (IGuildUser)context.User; if (!guildUser.GetRoles().Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant()) && guildUser.Id != guildUser.Guild.OwnerId) { return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands."))); } } int price; if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0) { var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false); if (!success) { return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command."))); } } } // Bot will ignore commands which are ran more often than what specified by // GlobalCommandsCooldown constant (miliseconds) if (!UsersOnShortCooldown.Add(context.Message.Author.Id)) { return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"You are on a global cooldown."))); } if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User)) { return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on a cooldown for you."))); } return(new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap))); } return(new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."))); }
public Task <IResult> ExecuteCommandAsync(SocketCommandContext context, string input, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteCommand(context, input.Substring(argPos), serviceProvider, multiMatchHandling);
public async Task <IResult> ExecuteCommand(SocketCommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { var searchResult = _commandService.Search(context, input); if (!searchResult.IsSuccess) { return(searchResult); } var commands = searchResult.Commands; var preconditionResults = new Dictionary <CommandMatch, PreconditionResult>(); foreach (var match in commands) { preconditionResults[match] = await match.Command.CheckPreconditionsAsync(context, services).ConfigureAwait(false); } var successfulPreconditions = preconditionResults .Where(x => x.Value.IsSuccess) .ToArray(); if (successfulPreconditions.Length == 0) { //All preconditions failed, return the one from the highest priority command var bestCandidate = preconditionResults .OrderByDescending(x => x.Key.Command.Priority) .FirstOrDefault(x => !x.Value.IsSuccess); return(bestCandidate.Value); } var parseResultsDict = new Dictionary <CommandMatch, ParseResult>(); foreach (var pair in successfulPreconditions) { var parseResult = await pair.Key.ParseAsync(context, searchResult, pair.Value, services).ConfigureAwait(false); if (parseResult.Error == CommandError.MultipleMatches) { IReadOnlyList <TypeReaderValue> argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } parseResultsDict[pair.Key] = parseResult; }
public async Task <IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { services = services ?? EmptyServiceProvider.Instance; var searchResult = Search(context, input); if (!searchResult.IsSuccess) { return(searchResult); } var commands = searchResult.Commands; for (int i = 0; i < commands.Count; i++) { var preconditionResult = await commands[i].CheckPreconditionsAsync(context, services).ConfigureAwait(false); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(preconditionResult); } else { continue; } } var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { IReadOnlyList <TypeReaderValue> argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(parseResult); } else { continue; } } } return(await commands[i].ExecuteAsync(context, parseResult, services).ConfigureAwait(false)); } return(SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload.")); }
public Task <(bool Success, string Error, CommandInfo Info)> ExecuteCommandAsync(CommandContext context, string input, int argPos, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteCommand(context, input.Substring(argPos), serviceProvider, multiMatchHandling);
public async Task <(bool Success, string Error, CommandInfo Info)> ExecuteCommandAsync(ICommandContext context, string input, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling, Action <ErrorCodeException> errorCodeHandler) => await ExecuteCommand(context, input.Substring(argPos), services, multiMatchHandling, errorCodeHandler);
public async Task <Tuple <Command, IResult> > Execute(IUserMessage message, string input, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { var searchResult = Search(message, input); if (!searchResult.IsSuccess) { return(new Tuple <Command, IResult>(null, searchResult)); } var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { var preconditionResult = await commands[i].CheckPreconditions(message); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, IResult>(null, searchResult)); } else { continue; } } var parseResult = await commands[i].Parse(message, searchResult, preconditionResult); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { TypeReaderValue[] argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, IResult>(null, parseResult)); } else { continue; } } } return(new Tuple <Command, IResult>(commands[i], await commands[i].Execute(message, parseResult))); } return(new Tuple <Command, IResult>(null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."))); }
/*/// <summary> * /// Executes the command. * /// </summary> * /// <param name="context">The context of the command.</param> * /// <param name="argPos">The position of which the command starts at.</param> * /// <param name="services">The service to be used in the command's dependency injection.</param> * /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> * /// <returns> * /// A task that represents the asynchronous execution operation. The task result contains the result * /// of the command execution. * /// </returns> * public new Task<IResult> ExecuteAsync(ICommandContext context, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { * return ExecuteAsync(context, context.Message.Content.Substring(argPos), services, multiMatchHandling); * } * /// <summary> * /// Executes the command. * /// </summary> * /// <param name="context">The context of the command.</param> * /// <param name="input">The command string.</param> * /// <param name="services">The service to be used in the command's dependency injection.</param> * /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> * /// <returns> * /// A task that represents the asynchronous execution operation. The task result contains the result * /// of the command execution. * /// </returns> * public new async Task<IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { * IResult result; * * result = await base.ExecuteAsync(context, input, services, multiMatchHandling).ConfigureAwait(false); * BestMatchResult bestMatchResult; * bestMatchResult = await FindBestMatchAsync(context, input, services, multiMatchHandling); * CommandInfo command = bestMatchResult.Command.Command; * if (bestMatchResult.IsSuccess) * result = await bestMatchResult.ExecuteAsync(); * else * result = bestMatchResult.Result; * * if (result is ExecuteResult execute && IsCommandAsync(command)) { * // Do nothing, this is not the result we're looking for. * return result; * } * * //await commandResultEvent.InvokeAsync(command, context, result); * * return result; * }*/ #endregion #region FindBestMatchAsync /// <summary> /// Performs a full search for the commands that match the input along with the parameters. /// </summary> /// <param name="context">The context of the command.</param> /// <param name="argPos">The position of which the command starts at.</param> /// <param name="services">The service to be used in the command's dependency injection.</param> /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> /// <returns> /// A task that represents the asynchronous match operation. The task result contains the result of the /// command search. /// </returns> public Task <BestMatchResult> FindBestMatchAsync(ICommandContext context, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { return(FindBestMatchAsync(context, context.Message.Content.Substring(argPos), services, multiMatchHandling)); }
/// <inheritdoc /> public async Task <IResult> ExecuteAsync(ICommandContext context, int argPos, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { return(await CommandService.ExecuteAsync(context, argPos, services, multiMatchHandling)); }
/// <summary> /// Executes the command. /// </summary> /// <param name="commandString">The context of the command.</param> /// <param name="argPos">The position of which the command starts at.</param> /// <param name="services">The service to be used in the command's dependency injection.</param> /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> /// <returns> /// A task that represents the asynchronous execution operation. The task result contains the result of the /// command execution. /// </returns> public Task <IResult> ExecuteAsync(string commandString, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { return(ExecuteAsync(commandString, commandString.Substring(argPos), services, multiMatchHandling)); }
/// <summary> /// Creates a new instance of <see cref="MultiMatchHandlingAttribute" />. /// </summary> /// <param name="multiMatchHandling">How multi matches will be handled for this module.</param> public MultiMatchHandlingAttribute(MultiMatchHandling multiMatchHandling) { Value = multiMatchHandling; }
/// <summary> /// Executes the command. /// </summary> /// <param name="context">The context of the command.</param> /// <param name="argPos">The position of which the command starts at.</param> /// <param name="services">The service to be used in the command's dependency injection.</param> /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> /// <returns> /// A task that represents the asynchronous execution operation. The task result contains the result of the /// command execution. /// </returns> public Task <IResult> ExecuteAsync(ITurnContext context, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteAsync(context, context.Activity.Text.Substring(argPos), services, multiMatchHandling);
/// <summary> /// Executes the command. /// </summary> /// <param name="context">The context of the command.</param> /// <param name="argPos">The position of which the command starts at.</param> /// <param name="services">The service to be used in the command's dependency injection.</param> /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> /// <returns> /// A task that represents the asynchronous execution operation. The task result contains the result of the /// command execution. /// </returns> public Task <IResult> ExecuteAsync(ICommandContext context, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteAsync(context, context.Message.Content.Substring(argPos), services, multiMatchHandling);
public async Task <Tuple <Command, PermissionCache, IResult> > ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) { var searchResult = _commandService.Search(message, input); if (!searchResult.IsSuccess) { return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult)); } var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { var preconditionResult = await commands[i].CheckPreconditions(message); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult)); } else { continue; } } var parseResult = await commands[i].Parse(message, searchResult, preconditionResult); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { TypeReaderValue[] argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, PermissionCache, IResult>(null, null, parseResult)); } else { continue; } } } var cmd = commands[i]; bool resetCommand = cmd.Name == "ResetPermissions"; PermissionCache pc; if (guild != null) { pc = Permissions.Cache.GetOrAdd(guild.Id, (id) => { using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.PermissionsFor(guild.Id); return(new PermissionCache() { Verbose = config.VerbosePermissions, RootPermission = config.RootPermission, PermRole = config.PermissionRole.Trim().ToLowerInvariant(), }); } }); int index; if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(message, cmd.Text, cmd.Module.Name, out index)) { var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand(guild)}** is preventing this action."; return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg))); } if (cmd.Module.Source.Name == typeof(Permissions).Name) //permissions, you must have special role { if (!((IGuildUser)user).Roles.Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant())) { return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands."))); } } } if (CmdCdsCommands.HasCooldown(cmd, guild, user)) { return(new Tuple <Command, PermissionCache, IResult>(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you."))); } return(new Tuple <Command, PermissionCache, IResult>(commands[i], null, await commands[i].Execute(message, parseResult))); } return(new Tuple <Command, PermissionCache, IResult>(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."))); }
/// <summary> /// Executes the command. /// </summary> /// <param name="context">The context of the command.</param> /// <param name="input">The command string.</param> /// <param name="services">The service to be used in the command's dependency injection.</param> /// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> /// <returns> /// A task that represents the asynchronous execution operation. The task result contains the result of the /// command execution. /// </returns> public async Task <IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { services = services ?? EmptyServiceProvider.Instance; var searchResult = Search(input); if (!searchResult.IsSuccess) { await _commandExecutedEvent.InvokeAsync(Optional.Create <CommandInfo>(), context, searchResult).ConfigureAwait(false); return(searchResult); } var commands = searchResult.Commands; var preconditionResults = new Dictionary <CommandMatch, PreconditionResult>(); foreach (var match in commands) { preconditionResults[match] = await match.Command.CheckPreconditionsAsync(context, services).ConfigureAwait(false); } var successfulPreconditions = preconditionResults .Where(x => x.Value.IsSuccess) .ToArray(); if (successfulPreconditions.Length == 0) { //All preconditions failed, return the one from the highest priority command var bestCandidate = preconditionResults .OrderByDescending(x => x.Key.Command.Priority) .FirstOrDefault(x => !x.Value.IsSuccess); await _commandExecutedEvent.InvokeAsync(bestCandidate.Key.Command, context, bestCandidate.Value).ConfigureAwait(false); return(bestCandidate.Value); } //If we get this far, at least one precondition was successful. var parseResultsDict = new Dictionary <CommandMatch, ParseResult>(); foreach (var pair in successfulPreconditions) { var parseResult = await pair.Key.ParseAsync(context, searchResult, pair.Value, services).ConfigureAwait(false); if (parseResult.Error == CommandError.MultipleMatches) { IReadOnlyList <TypeReaderValue> argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } parseResultsDict[pair.Key] = parseResult; } // Calculates the 'score' of a command given a parse result float CalculateScore(CommandMatch match, ParseResult parseResult) { float argValuesScore = 0, paramValuesScore = 0; if (match.Command.Parameters.Count > 0) { var argValuesSum = parseResult.ArgValues?.Sum(x => x.Values.OrderByDescending(y => y.Score).FirstOrDefault().Score) ?? 0; var paramValuesSum = parseResult.ParamValues?.Sum(x => x.Values.OrderByDescending(y => y.Score).FirstOrDefault().Score) ?? 0; argValuesScore = argValuesSum / match.Command.Parameters.Count; paramValuesScore = paramValuesSum / match.Command.Parameters.Count; } var totalArgsScore = (argValuesScore + paramValuesScore) / 2; return(match.Command.Priority + totalArgsScore * 0.99f); } //Order the parse results by their score so that we choose the most likely result to execute var parseResults = parseResultsDict .OrderByDescending(x => CalculateScore(x.Key, x.Value)); var successfulParses = parseResults .Where(x => x.Value.IsSuccess) .ToArray(); if (successfulParses.Length == 0) { //All parses failed, return the one from the highest priority command, using score as a tie breaker var bestMatch = parseResults .FirstOrDefault(x => !x.Value.IsSuccess); await _commandExecutedEvent.InvokeAsync(bestMatch.Key.Command, context, bestMatch.Value).ConfigureAwait(false); return(bestMatch.Value); } //If we get this far, at least one parse was successful. Execute the most likely overload. var chosenOverload = successfulParses[0]; var result = await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false); if (!result.IsSuccess && !(result is RuntimeResult)) // succesful results raise the event in CommandInfo#ExecuteInternalAsync (have to raise it there b/c deffered execution) { await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result); } return(result); }
public Task <Tuple <Command, IResult> > Execute(IUserMessage message, int argPos, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => Execute(message, message.Content.Substring(argPos), multiMatchHandling);