| @@ -18,8 +18,8 @@ namespace Discord.Commands | |||||
| public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | ||||
| => Command.CheckPreconditionsAsync(context, services); | => Command.CheckPreconditionsAsync(context, services); | ||||
| public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult, PreconditionResult preconditionResult = null) | |||||
| => Command.ParseAsync(context, Alias.Length, searchResult, preconditionResult); | |||||
| public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | |||||
| => Command.ParseAsync(context, Alias.Length, searchResult, preconditionResult, services); | |||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IServiceProvider services) | public Task<ExecuteResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IServiceProvider services) | ||||
| => Command.ExecuteAsync(context, argList, paramList, services); | => Command.ExecuteAsync(context, argList, paramList, services); | ||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | ||||
| @@ -1,4 +1,5 @@ | |||||
| using System.Collections.Immutable; | |||||
| using System; | |||||
| using System.Collections.Immutable; | |||||
| using System.Text; | using System.Text; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| @@ -13,7 +14,7 @@ namespace Discord.Commands | |||||
| QuotedParameter | QuotedParameter | ||||
| } | } | ||||
| public static async Task<ParseResult> ParseArgs(CommandInfo command, ICommandContext context, string input, int startPos) | |||||
| public static async Task<ParseResult> ParseArgs(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos) | |||||
| { | { | ||||
| ParameterInfo curParam = null; | ParameterInfo curParam = null; | ||||
| StringBuilder argBuilder = new StringBuilder(input.Length); | StringBuilder argBuilder = new StringBuilder(input.Length); | ||||
| @@ -110,7 +111,7 @@ namespace Discord.Commands | |||||
| if (curParam == null) | if (curParam == null) | ||||
| return ParseResult.FromError(CommandError.BadArgCount, "The input text has too many parameters."); | return ParseResult.FromError(CommandError.BadArgCount, "The input text has too many parameters."); | ||||
| var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false); | |||||
| var typeReaderResult = await curParam.Parse(context, argString, services).ConfigureAwait(false); | |||||
| if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches) | if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches) | ||||
| return ParseResult.FromError(typeReaderResult); | return ParseResult.FromError(typeReaderResult); | ||||
| @@ -133,7 +134,7 @@ namespace Discord.Commands | |||||
| if (curParam != null && curParam.IsRemainder) | if (curParam != null && curParam.IsRemainder) | ||||
| { | { | ||||
| var typeReaderResult = await curParam.Parse(context, argBuilder.ToString()).ConfigureAwait(false); | |||||
| var typeReaderResult = await curParam.Parse(context, argBuilder.ToString(), services).ConfigureAwait(false); | |||||
| if (!typeReaderResult.IsSuccess) | if (!typeReaderResult.IsSuccess) | ||||
| return ParseResult.FromError(typeReaderResult); | return ParseResult.FromError(typeReaderResult); | ||||
| argList.Add(typeReaderResult); | argList.Add(typeReaderResult); | ||||
| @@ -267,7 +267,7 @@ namespace Discord.Commands | |||||
| continue; | continue; | ||||
| } | } | ||||
| var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); | |||||
| var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult, services).ConfigureAwait(false); | |||||
| if (!parseResult.IsSuccess) | if (!parseResult.IsSuccess) | ||||
| { | { | ||||
| if (parseResult.Error == CommandError.MultipleMatches) | if (parseResult.Error == CommandError.MultipleMatches) | ||||
| @@ -105,15 +105,17 @@ namespace Discord.Commands | |||||
| return PreconditionResult.FromSuccess(); | return PreconditionResult.FromSuccess(); | ||||
| } | } | ||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null) | |||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | |||||
| { | { | ||||
| services = services ?? EmptyServiceProvider.Instance; | |||||
| if (!searchResult.IsSuccess) | if (!searchResult.IsSuccess) | ||||
| return ParseResult.FromError(searchResult); | return ParseResult.FromError(searchResult); | ||||
| if (preconditionResult != null && !preconditionResult.IsSuccess) | if (preconditionResult != null && !preconditionResult.IsSuccess) | ||||
| return ParseResult.FromError(preconditionResult); | return ParseResult.FromError(preconditionResult); | ||||
| string input = searchResult.Text.Substring(startIndex); | string input = searchResult.Text.Substring(startIndex); | ||||
| return await CommandParser.ParseArgs(this, context, input, 0).ConfigureAwait(false); | |||||
| return await CommandParser.ParseArgs(this, context, services, input, 0).ConfigureAwait(false); | |||||
| } | } | ||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | ||||
| @@ -54,9 +54,10 @@ namespace Discord.Commands | |||||
| return PreconditionResult.FromSuccess(); | return PreconditionResult.FromSuccess(); | ||||
| } | } | ||||
| public async Task<TypeReaderResult> Parse(ICommandContext context, string input) | |||||
| public async Task<TypeReaderResult> Parse(ICommandContext context, string input, IServiceProvider services = null) | |||||
| { | { | ||||
| return await _reader.Read(context, input).ConfigureAwait(false); | |||||
| services = services ?? EmptyServiceProvider.Instance; | |||||
| return await _reader.Read(context, input, services).ConfigureAwait(false); | |||||
| } | } | ||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| @@ -9,7 +9,7 @@ namespace Discord.Commands | |||||
| internal class ChannelTypeReader<T> : TypeReader | internal class ChannelTypeReader<T> : TypeReader | ||||
| where T : class, IChannel | where T : class, IChannel | ||||
| { | { | ||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| if (context.Guild != null) | if (context.Guild != null) | ||||
| { | { | ||||
| @@ -44,12 +44,11 @@ namespace Discord.Commands | |||||
| _enumsByValue = byValueBuilder.ToImmutable(); | _enumsByValue = byValueBuilder.ToImmutable(); | ||||
| } | } | ||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| T baseValue; | |||||
| object enumValue; | object enumValue; | ||||
| if (_tryParse(input, out baseValue)) | |||||
| if (_tryParse(input, out T baseValue)) | |||||
| { | { | ||||
| if (_enumsByValue.TryGetValue(baseValue, out enumValue)) | if (_enumsByValue.TryGetValue(baseValue, out enumValue)) | ||||
| return Task.FromResult(TypeReaderResult.FromSuccess(enumValue)); | return Task.FromResult(TypeReaderResult.FromSuccess(enumValue)); | ||||
| @@ -1,4 +1,5 @@ | |||||
| using System.Globalization; | |||||
| using System; | |||||
| using System.Globalization; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| @@ -6,15 +7,14 @@ namespace Discord.Commands | |||||
| internal class MessageTypeReader<T> : TypeReader | internal class MessageTypeReader<T> : TypeReader | ||||
| where T : class, IMessage | where T : class, IMessage | ||||
| { | { | ||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| ulong id; | ulong id; | ||||
| //By Id (1.0) | //By Id (1.0) | ||||
| if (ulong.TryParse(input, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | if (ulong.TryParse(input, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | ||||
| { | { | ||||
| var msg = await context.Channel.GetMessageAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) as T; | |||||
| if (msg != null) | |||||
| if (await context.Channel.GetMessageAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) is T msg) | |||||
| return TypeReaderResult.FromSuccess(msg); | return TypeReaderResult.FromSuccess(msg); | ||||
| } | } | ||||
| @@ -21,10 +21,9 @@ namespace Discord.Commands | |||||
| _tryParse = PrimitiveParsers.Get<T>(); | _tryParse = PrimitiveParsers.Get<T>(); | ||||
| } | } | ||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| T value; | |||||
| if (_tryParse(input, out value)) | |||||
| if (_tryParse(input, out T value)) | |||||
| return Task.FromResult(TypeReaderResult.FromSuccess(value)); | return Task.FromResult(TypeReaderResult.FromSuccess(value)); | ||||
| return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Failed to parse {typeof(T).Name}")); | return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Failed to parse {typeof(T).Name}")); | ||||
| } | } | ||||
| @@ -9,7 +9,7 @@ namespace Discord.Commands | |||||
| internal class RoleTypeReader<T> : TypeReader | internal class RoleTypeReader<T> : TypeReader | ||||
| where T : class, IRole | where T : class, IRole | ||||
| { | { | ||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| ulong id; | ulong id; | ||||
| @@ -1,9 +1,10 @@ | |||||
| using System.Threading.Tasks; | |||||
| using System; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| public abstract class TypeReader | public abstract class TypeReader | ||||
| { | { | ||||
| public abstract Task<TypeReaderResult> Read(ICommandContext context, string input); | |||||
| public abstract Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services); | |||||
| } | } | ||||
| } | } | ||||
| @@ -10,7 +10,7 @@ namespace Discord.Commands | |||||
| internal class UserTypeReader<T> : TypeReader | internal class UserTypeReader<T> : TypeReader | ||||
| where T : class, IUser | where T : class, IUser | ||||
| { | { | ||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input) | |||||
| public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services) | |||||
| { | { | ||||
| var results = new Dictionary<ulong, TypeReaderValue>(); | var results = new Dictionary<ulong, TypeReaderValue>(); | ||||
| IReadOnlyCollection<IUser> channelUsers = (await context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten().ConfigureAwait(false)).ToArray(); //TODO: must be a better way? | IReadOnlyCollection<IUser> channelUsers = (await context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten().ConfigureAwait(false)).ToArray(); //TODO: must be a better way? | ||||
| @@ -43,8 +43,7 @@ namespace Discord.Commands | |||||
| if (index >= 0) | if (index >= 0) | ||||
| { | { | ||||
| string username = input.Substring(0, index); | string username = input.Substring(0, index); | ||||
| ushort discriminator; | |||||
| if (ushort.TryParse(input.Substring(index + 1), out discriminator)) | |||||
| if (ushort.TryParse(input.Substring(index + 1), out ushort discriminator)) | |||||
| { | { | ||||
| var channelUser = channelUsers.FirstOrDefault(x => x.DiscriminatorValue == discriminator && | var channelUser = channelUsers.FirstOrDefault(x => x.DiscriminatorValue == discriminator && | ||||
| string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)); | string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)); | ||||