You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
2.6 KiB
56 lines
2.6 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Discord.Commands
|
|
{
|
|
/// <summary>
|
|
/// A <see cref="TypeReader"/> for parsing objects implementing <see cref="IChannel"/>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This <see cref="TypeReader"/> is shipped with Discord.Net and is used by default to parse any
|
|
/// <see cref="IChannel"/> implemented object within a command. The TypeReader will attempt to first parse the
|
|
/// input by mention, then the snowflake identifier, then by name; the highest candidate will be chosen as the
|
|
/// final output; otherwise, an erroneous <see cref="TypeReaderResult"/> is returned.
|
|
/// </remarks>
|
|
/// <typeparam name="T">The type to be checked; must implement <see cref="IChannel"/>.</typeparam>
|
|
public class ChannelTypeReader<T> : TypeReader
|
|
where T : class, IChannel
|
|
{
|
|
/// <inheritdoc />
|
|
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
|
{
|
|
if (context.Guild != null)
|
|
{
|
|
var results = new Dictionary<ulong, TypeReaderValue>();
|
|
var channels = await context.Guild.GetChannelsAsync(CacheMode.CacheOnly).ConfigureAwait(false);
|
|
|
|
//By Mention (1.0)
|
|
if (MentionUtils.TryParseChannel(input, out ulong id))
|
|
AddResult(results, await context.Guild.GetChannelAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) as T, 1.00f);
|
|
|
|
//By Id (0.9)
|
|
if (ulong.TryParse(input, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
|
AddResult(results, await context.Guild.GetChannelAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) as T, 0.90f);
|
|
|
|
//By Name (0.7-0.8)
|
|
foreach (var channel in channels.Where(x => string.Equals(input, x.Name, StringComparison.OrdinalIgnoreCase)))
|
|
AddResult(results, channel as T, channel.Name == input ? 0.80f : 0.70f);
|
|
|
|
if (results.Count > 0)
|
|
return TypeReaderResult.FromSuccess(results.Values.ToReadOnlyCollection());
|
|
}
|
|
|
|
return TypeReaderResult.FromError(CommandError.ObjectNotFound, "Channel not found.");
|
|
}
|
|
|
|
private void AddResult(Dictionary<ulong, TypeReaderValue> results, T channel, float score)
|
|
{
|
|
if (channel != null && !results.ContainsKey(channel.Id))
|
|
results.Add(channel.Id, new TypeReaderValue(channel, score));
|
|
}
|
|
}
|
|
}
|