@@ -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)); | ||||