| @@ -13,6 +13,19 @@ namespace Discord.Commands | |||||
| Parameter, | Parameter, | ||||
| QuotedParameter | QuotedParameter | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Checks to see if the supplied character is a quotation mark | |||||
| /// from either the default " character, or the list of aliases | |||||
| /// if they are provided. | |||||
| /// </summary> | |||||
| /// <param name="c"></param> | |||||
| /// <param name="aliases"></param> | |||||
| private static bool isQuotationChar(char c, char[] aliases) | |||||
| { | |||||
| if (aliases == null) return c == '\"'; | |||||
| return Array.Exists(aliases, x => x == c); | |||||
| } | |||||
| public static async Task<ParseResult> ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos) | public static async Task<ParseResult> ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos) | ||||
| { | { | ||||
| @@ -74,7 +87,7 @@ namespace Discord.Commands | |||||
| argBuilder.Append(c); | argBuilder.Append(c); | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (c == '\"') | |||||
| if (isQuotationChar(c, command._quotationAliases)) | |||||
| { | { | ||||
| curPart = ParserPart.QuotedParameter; | curPart = ParserPart.QuotedParameter; | ||||
| continue; | continue; | ||||
| @@ -97,7 +110,7 @@ namespace Discord.Commands | |||||
| } | } | ||||
| else if (curPart == ParserPart.QuotedParameter) | else if (curPart == ParserPart.QuotedParameter) | ||||
| { | { | ||||
| if (c == '\"') | |||||
| if (isQuotationChar(c, command._quotationAliases)) | |||||
| { | { | ||||
| argString = argBuilder.ToString(); //Remove quotes | argString = argBuilder.ToString(); //Remove quotes | ||||
| lastArgEndPos = curPos + 1; | lastArgEndPos = curPos + 1; | ||||
| @@ -32,6 +32,7 @@ namespace Discord.Commands | |||||
| internal readonly RunMode _defaultRunMode; | internal readonly RunMode _defaultRunMode; | ||||
| internal readonly Logger _cmdLogger; | internal readonly Logger _cmdLogger; | ||||
| internal readonly LogManager _logManager; | internal readonly LogManager _logManager; | ||||
| internal readonly char[] _quotationMarkAliases; | |||||
| public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x); | public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x); | ||||
| public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands); | public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands); | ||||
| @@ -44,6 +45,7 @@ namespace Discord.Commands | |||||
| _throwOnError = config.ThrowOnError; | _throwOnError = config.ThrowOnError; | ||||
| _separatorChar = config.SeparatorChar; | _separatorChar = config.SeparatorChar; | ||||
| _defaultRunMode = config.DefaultRunMode; | _defaultRunMode = config.DefaultRunMode; | ||||
| _quotationMarkAliases = config.QuotationMarkAliases; | |||||
| if (_defaultRunMode == RunMode.Default) | if (_defaultRunMode == RunMode.Default) | ||||
| throw new InvalidOperationException("The default run mode cannot be set to Default."); | throw new InvalidOperationException("The default run mode cannot be set to Default."); | ||||
| @@ -276,7 +278,7 @@ namespace Discord.Commands | |||||
| public async Task<IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | public async Task<IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | ||||
| { | { | ||||
| services = services ?? EmptyServiceProvider.Instance; | services = services ?? EmptyServiceProvider.Instance; | ||||
| var searchResult = Search(context, input); | var searchResult = Search(context, input); | ||||
| if (!searchResult.IsSuccess) | if (!searchResult.IsSuccess) | ||||
| return searchResult; | return searchResult; | ||||
| @@ -15,5 +15,8 @@ | |||||
| /// <summary> Determines whether RunMode.Sync commands should push exceptions up to the caller. </summary> | /// <summary> Determines whether RunMode.Sync commands should push exceptions up to the caller. </summary> | ||||
| public bool ThrowOnError { get; set; } = true; | public bool ThrowOnError { get; set; } = true; | ||||
| /// <summary> List of aliases for string parsing </summary> | |||||
| public char[] QuotationMarkAliases { get; set; } = new char[] { '“', '”', '\'', '«', '»', '‹', '›' }; | |||||
| } | } | ||||
| } | } | ||||
| @@ -19,6 +19,7 @@ namespace Discord.Commands | |||||
| private static readonly ConcurrentDictionary<Type, Func<IEnumerable<object>, object>> _arrayConverters = new ConcurrentDictionary<Type, Func<IEnumerable<object>, object>>(); | private static readonly ConcurrentDictionary<Type, Func<IEnumerable<object>, object>> _arrayConverters = new ConcurrentDictionary<Type, Func<IEnumerable<object>, object>>(); | ||||
| private readonly Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> _action; | private readonly Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> _action; | ||||
| internal readonly char[] _quotationAliases; | |||||
| public ModuleInfo Module { get; } | public ModuleInfo Module { get; } | ||||
| public string Name { get; } | public string Name { get; } | ||||
| @@ -64,6 +65,7 @@ namespace Discord.Commands | |||||
| HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false; | HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false; | ||||
| _action = builder.Callback; | _action = builder.Callback; | ||||
| _quotationAliases = service._quotationMarkAliases; | |||||
| } | } | ||||
| public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | ||||
| @@ -107,7 +109,7 @@ namespace Discord.Commands | |||||
| return PreconditionResult.FromSuccess(); | return PreconditionResult.FromSuccess(); | ||||
| } | } | ||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | |||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null, char[] quotationAliases = null) | |||||
| { | { | ||||
| services = services ?? EmptyServiceProvider.Instance; | services = services ?? EmptyServiceProvider.Instance; | ||||