Implemented command type readers, parser and service.
This commit is contained in:
48
src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
Normal file
48
src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
internal class ChannelTypeReader<T> : TypeReader
|
||||
where T : class, IChannel
|
||||
{
|
||||
public override async Task<TypeReaderResult> Read(IMessage context, string input)
|
||||
{
|
||||
IGuildChannel guildChannel = context.Channel as IGuildChannel;
|
||||
IChannel result = null;
|
||||
|
||||
if (guildChannel != null)
|
||||
{
|
||||
//By Id
|
||||
ulong id;
|
||||
if (MentionUtils.TryParseChannel(input, out id) || ulong.TryParse(input, out id))
|
||||
{
|
||||
var channel = await guildChannel.Guild.GetChannelAsync(id).ConfigureAwait(false);
|
||||
if (channel != null)
|
||||
result = channel;
|
||||
}
|
||||
|
||||
//By Name
|
||||
if (result == null)
|
||||
{
|
||||
var channels = await guildChannel.Guild.GetChannelsAsync().ConfigureAwait(false);
|
||||
var filteredChannels = channels.Where(x => string.Equals(input, x.Name, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
if (filteredChannels.Length > 1)
|
||||
return TypeReaderResult.FromError(CommandError.MultipleMatches, "Multiple channels found.");
|
||||
else if (filteredChannels.Length == 1)
|
||||
result = filteredChannels[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
return TypeReaderResult.FromError(CommandError.ObjectNotFound, "Channel not found.");
|
||||
|
||||
T castResult = result as T;
|
||||
if (castResult == null)
|
||||
return TypeReaderResult.FromError(CommandError.CastFailed, $"Channel is not a {typeof(T).Name}.");
|
||||
else
|
||||
return TypeReaderResult.FromSuccess(castResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/Discord.Net.Commands/Readers/GenericTypeReader.cs
Normal file
17
src/Discord.Net.Commands/Readers/GenericTypeReader.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
internal class GenericTypeReader : TypeReader
|
||||
{
|
||||
private readonly Func<IMessage, string, Task<TypeReaderResult>> _action;
|
||||
|
||||
public GenericTypeReader(Func<IMessage, string, Task<TypeReaderResult>> action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> Read(IMessage context, string input) => _action(context, input);
|
||||
}
|
||||
}
|
||||
24
src/Discord.Net.Commands/Readers/MessageTypeReader.cs
Normal file
24
src/Discord.Net.Commands/Readers/MessageTypeReader.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
internal class MessageTypeReader : TypeReader
|
||||
{
|
||||
public override Task<TypeReaderResult> Read(IMessage context, string input)
|
||||
{
|
||||
//By Id
|
||||
ulong id;
|
||||
if (ulong.TryParse(input, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
||||
{
|
||||
var msg = context.Channel.GetCachedMessage(id);
|
||||
if (msg == null)
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ObjectNotFound, "Message not found."));
|
||||
else
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(msg));
|
||||
}
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse Message Id."));
|
||||
}
|
||||
}
|
||||
}
|
||||
36
src/Discord.Net.Commands/Readers/RoleTypeReader.cs
Normal file
36
src/Discord.Net.Commands/Readers/RoleTypeReader.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
internal class RoleTypeReader : TypeReader
|
||||
{
|
||||
public override Task<TypeReaderResult> Read(IMessage context, string input)
|
||||
{
|
||||
IGuildChannel guildChannel = context.Channel as IGuildChannel;
|
||||
|
||||
if (guildChannel != null)
|
||||
{
|
||||
//By Id
|
||||
ulong id;
|
||||
if (MentionUtils.TryParseRole(input, out id) || ulong.TryParse(input, out id))
|
||||
{
|
||||
var channel = guildChannel.Guild.GetRole(id);
|
||||
if (channel != null)
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(channel));
|
||||
}
|
||||
|
||||
//By Name
|
||||
var roles = guildChannel.Guild.Roles;
|
||||
var filteredRoles = roles.Where(x => string.Equals(input, x.Name, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
if (filteredRoles.Length > 1)
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.MultipleMatches, "Multiple roles found."));
|
||||
else if (filteredRoles.Length == 1)
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(filteredRoles[0]));
|
||||
}
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ObjectNotFound, "Role not found."));
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/Discord.Net.Commands/Readers/TypeReader.cs
Normal file
9
src/Discord.Net.Commands/Readers/TypeReader.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public abstract class TypeReader
|
||||
{
|
||||
public abstract Task<TypeReaderResult> Read(IMessage context, string input);
|
||||
}
|
||||
}
|
||||
66
src/Discord.Net.Commands/Readers/UserTypeReader.cs
Normal file
66
src/Discord.Net.Commands/Readers/UserTypeReader.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
internal class UserTypeReader<T> : TypeReader
|
||||
where T : class, IUser
|
||||
{
|
||||
public override async Task<TypeReaderResult> Read(IMessage context, string input)
|
||||
{
|
||||
IGuildChannel guildChannel = context.Channel as IGuildChannel;
|
||||
IUser result = null;
|
||||
|
||||
if (guildChannel != null)
|
||||
{
|
||||
//By Id
|
||||
ulong id;
|
||||
if (MentionUtils.TryParseUser(input, out id) || ulong.TryParse(input, out id))
|
||||
{
|
||||
var user = await guildChannel.Guild.GetUserAsync(id).ConfigureAwait(false);
|
||||
if (user != null)
|
||||
result = user;
|
||||
}
|
||||
|
||||
//By Username + Discriminator
|
||||
if (result == null)
|
||||
{
|
||||
int index = input.LastIndexOf('#');
|
||||
if (index >= 0)
|
||||
{
|
||||
string username = input.Substring(0, index);
|
||||
ushort discriminator;
|
||||
if (ushort.TryParse(input.Substring(index + 1), out discriminator))
|
||||
{
|
||||
var users = await guildChannel.Guild.GetUsersAsync().ConfigureAwait(false);
|
||||
result = users.Where(x =>
|
||||
x.DiscriminatorValue == discriminator &&
|
||||
string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//By Username
|
||||
if (result == null)
|
||||
{
|
||||
var users = await guildChannel.Guild.GetUsersAsync().ConfigureAwait(false);
|
||||
var filteredUsers = users.Where(x => string.Equals(input, x.Username, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
if (filteredUsers.Length > 1)
|
||||
return TypeReaderResult.FromError(CommandError.MultipleMatches, "Multiple users found.");
|
||||
else if (filteredUsers.Length == 1)
|
||||
result = filteredUsers[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
return TypeReaderResult.FromError(CommandError.ObjectNotFound, "User not found.");
|
||||
|
||||
T castResult = result as T;
|
||||
if (castResult == null)
|
||||
return TypeReaderResult.FromError(CommandError.CastFailed, $"User is not a {typeof(T).Name}.");
|
||||
else
|
||||
return TypeReaderResult.FromSuccess(castResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user