Added remaining gateway events, added IAudioChannel, added CacheModes

This commit is contained in:
RogueException
2016-10-04 07:32:26 -03:00
parent e038475ab4
commit 4678544fed
58 changed files with 1685 additions and 855 deletions

View File

@@ -0,0 +1,6 @@
namespace Discord.Rest
{
public interface IRestAudioChannel : IAudioChannel
{
}
}

View File

@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace Discord.Rest
{
public interface IRestMessageChannel : IMessageChannel
{
/// <summary> Sends a message to this message channel. </summary>
new Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false);
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false);
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false);
/// <summary> Gets a message from this message channel with the given id, or null if not found. </summary>
Task<RestMessage> GetMessageAsync(ulong id);
/// <summary> Gets the last N messages from this message channel. </summary>
IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch);
/// <summary> Gets a collection of messages in this channel. </summary>
IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch);
/// <summary> Gets a collection of pinned messages in this channel. </summary>
new Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync();
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Discord.Rest
{
public interface IRestPrivateChannel : IPrivateChannel
{
new IReadOnlyCollection<RestUser> Recipients { get; }
}
}

View File

@@ -23,6 +23,17 @@ namespace Discord.Rest
return RestTextChannel.Create(discord, model);
case ChannelType.Voice:
return RestVoiceChannel.Create(discord, model);
case ChannelType.DM:
case ChannelType.Group:
return CreatePrivate(discord, model) as RestChannel;
default:
throw new InvalidOperationException($"Unexpected channel type: {model.Type}");
}
}
internal static IRestPrivateChannel CreatePrivate(BaseDiscordClient discord, Model model)
{
switch (model.Type)
{
case ChannelType.DM:
return RestDMChannel.Create(discord, model);
case ChannelType.Group:
@@ -35,14 +46,10 @@ namespace Discord.Rest
public abstract Task UpdateAsync();
//IChannel
IReadOnlyCollection<IUser> IChannel.CachedUsers => ImmutableArray.Create<IUser>();
IUser IChannel.GetCachedUser(ulong id)
=> null;
Task<IUser> IChannel.GetUserAsync(ulong id)
=> Task.FromResult<IUser>(null);
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync()
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>().ToAsyncEnumerable();
//IChannel
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult<IUser>(null); //Overriden
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>().ToAsyncEnumerable(); //Overriden
}
}

View File

@@ -10,7 +10,7 @@ using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestDMChannel : RestChannel, IDMChannel, IUpdateable
public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel, IUpdateable
{
public RestUser CurrentUser { get; private set; }
public RestUser Recipient { get; private set; }
@@ -75,23 +75,39 @@ namespace Discord.Rest
public override string ToString() => $"@{Recipient}";
private string DebuggerDisplay => $"@{Recipient} ({Id}, DM)";
//IDMChannel
IUser IDMChannel.Recipient => Recipient;
//IRestPrivateChannel
IReadOnlyCollection<RestUser> IRestPrivateChannel.Recipients => ImmutableArray.Create(Recipient);
//IPrivateChannel
IReadOnlyCollection<IUser> IPrivateChannel.Recipients => ImmutableArray.Create<IUser>(Recipient);
//IMessageChannel
IReadOnlyCollection<IMessage> IMessageChannel.CachedMessages => ImmutableArray.Create<IMessage>();
IMessage IMessageChannel.GetCachedMessage(ulong id) => null;
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id)
=> await GetMessageAsync(id);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit)
=> GetMessagesAsync(limit);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit)
=> GetMessagesAsync(fromMessageId, dir, limit);
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync()
=> await GetPinnedMessagesAsync().ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS)
@@ -103,14 +119,10 @@ namespace Discord.Rest
IDisposable IMessageChannel.EnterTypingState()
=> EnterTypingState();
//IChannel
IReadOnlyCollection<IUser> IChannel.CachedUsers => Users;
IUser IChannel.GetCachedUser(ulong id)
=> GetUser(id);
Task<IUser> IChannel.GetUserAsync(ulong id)
//IChannel
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult<IUser>(GetUser(id));
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync()
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>().ToAsyncEnumerable();
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
}
}

View File

@@ -10,11 +10,11 @@ using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestGroupChannel : RestChannel, IGroupChannel, IUpdateable
public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel, IUpdateable
{
private string _iconId;
private ImmutableDictionary<ulong, RestGroupUser> _users;
public string Name { get; private set; }
public IReadOnlyCollection<RestGroupUser> Users => _users.ToReadOnlyCollection();
@@ -86,20 +86,34 @@ namespace Discord.Rest
public IDisposable EnterTypingState()
=> ChannelHelper.EnterTypingState(this, Discord);
//ISocketPrivateChannel
IReadOnlyCollection<RestUser> IRestPrivateChannel.Recipients => Recipients;
//IPrivateChannel
IReadOnlyCollection<IUser> IPrivateChannel.Recipients => Recipients;
//IMessageChannel
IReadOnlyCollection<IMessage> IMessageChannel.CachedMessages => ImmutableArray.Create<IMessage>();
IMessage IMessageChannel.GetCachedMessage(ulong id)
=> null;
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id)
=> await GetMessageAsync(id);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit)
=> GetMessagesAsync(limit);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit)
=> GetMessagesAsync(fromMessageId, dir, limit);
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync()
=> await GetPinnedMessagesAsync();
@@ -112,14 +126,10 @@ namespace Discord.Rest
IDisposable IMessageChannel.EnterTypingState()
=> EnterTypingState();
//IChannel
IReadOnlyCollection<IUser> IChannel.CachedUsers => Users;
IUser IChannel.GetCachedUser(ulong id)
=> GetUser(id);
Task<IUser> IChannel.GetUserAsync(ulong id)
//IChannel
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult(GetUser(id));
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync()
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
}
}

View File

@@ -135,24 +135,16 @@ namespace Discord.Rest
=> await RemovePermissionOverwriteAsync(role);
async Task IGuildChannel.RemovePermissionOverwriteAsync(IUser user)
=> await RemovePermissionOverwriteAsync(user);
IReadOnlyCollection<IGuildUser> IGuildChannel.CachedUsers
=> ImmutableArray.Create<IGuildUser>();
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync()
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>().ToAsyncEnumerable(); //Overriden in Text/Voice //TODO: Does this actually override?
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id)
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult<IGuildUser>(null); //Overriden in Text/Voice //TODO: Does this actually override?
IGuildUser IGuildChannel.GetCachedUser(ulong id)
=> null;
//IChannel
IReadOnlyCollection<IUser> IChannel.CachedUsers
=> ImmutableArray.Create<IUser>();
IUser IChannel.GetCachedUser(ulong id)
=> null;
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync()
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>().ToAsyncEnumerable(); //Overriden in Text/Voice //TODO: Does this actually override?
Task<IUser> IChannel.GetUserAsync(ulong id)
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult<IUser>(null); //Overriden in Text/Voice //TODO: Does this actually override?
}
}

View File

@@ -4,13 +4,14 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestTextChannel : RestGuildChannel, ITextChannel
public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel
{
public string Topic { get; private set; }
@@ -67,22 +68,43 @@ namespace Discord.Rest
=> ChannelHelper.EnterTypingState(this, Discord);
//IGuildChannel
async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id)
=> await GetUserAsync(id);
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync()
=> GetUsersAsync();
async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetUserAsync(id);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetUsersAsync();
else
return ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>().ToAsyncEnumerable();
}
//IMessageChannel
IReadOnlyCollection<IMessage> IMessageChannel.CachedMessages
=> ImmutableArray.Create<IMessage>();
IMessage IMessageChannel.GetCachedMessage(ulong id)
=> null;
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id)
=> await GetMessageAsync(id);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit)
=> GetMessagesAsync(limit);
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit)
=> GetMessagesAsync(fromMessageId, dir, limit);
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit);
else
return ImmutableArray.Create<IReadOnlyCollection<IMessage>>().ToAsyncEnumerable();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync()
=> await GetPinnedMessagesAsync();

View File

@@ -11,7 +11,7 @@ using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel
{
public int Bitrate { get; private set; }
public int UserLimit { get; private set; }
@@ -41,9 +41,9 @@ namespace Discord.Rest
Task<IAudioClient> IVoiceChannel.ConnectAsync() { throw new NotSupportedException(); }
//IGuildChannel
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id)
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode)
=> Task.FromResult<IGuildUser>(null);
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync()
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode)
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>().ToAsyncEnumerable();
}
}

View File

@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Discord.API.Rest;
using Model = Discord.API.Guild;
using System.Linq;
namespace Discord.Rest
{
@@ -149,7 +150,7 @@ namespace Discord.Rest
return null;
}
public async Task<IRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?), bool isHoisted = false)
public async Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?), bool isHoisted = false)
{
var role = await GuildHelper.CreateRoleAsync(this, Discord, name, permissions, color, isHoisted);
_roles = _roles.Add(role.Id, role);
@@ -157,8 +158,8 @@ namespace Discord.Rest
}
//Users
public Task<IReadOnlyCollection<RestGuildUser>> GetUsersAsync()
=> GuildHelper.GetUsersAsync(this, Discord);
public IAsyncEnumerable<IReadOnlyCollection<RestGuildUser>> GetUsersAsync()
=> GuildHelper.GetUsersAsync(this, Discord).ToAsyncEnumerable();
public Task<RestGuildUser> GetUserAsync(ulong id)
=> GuildHelper.GetUserAsync(this, Discord, id);
public Task<RestGuildUser> GetCurrentUserAsync()
@@ -170,19 +171,26 @@ namespace Discord.Rest
//IGuild
bool IGuild.Available => true;
IAudioClient IGuild.AudioClient => null;
IReadOnlyCollection<IGuildUser> IGuild.CachedUsers => ImmutableArray.Create<IGuildUser>();
IRole IGuild.EveryoneRole => EveryoneRole;
IReadOnlyCollection<IRole> IGuild.Roles => Roles;
async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync()
=> await GetBansAsync();
async Task<IReadOnlyCollection<IGuildChannel>> IGuild.GetChannelsAsync()
=> await GetChannelsAsync();
async Task<IGuildChannel> IGuild.GetChannelAsync(ulong id)
=> await GetChannelAsync(id);
IGuildChannel IGuild.GetCachedChannel(ulong id)
=> null;
async Task<IReadOnlyCollection<IGuildChannel>> IGuild.GetChannelsAsync(CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetChannelsAsync();
else
return ImmutableArray.Create<IGuildChannel>();
}
async Task<IGuildChannel> IGuild.GetChannelAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetChannelAsync(id);
else
return null;
}
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name)
=> await CreateTextChannelAsync(name);
async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name)
@@ -198,15 +206,30 @@ namespace Discord.Rest
IRole IGuild.GetRole(ulong id)
=> GetRole(id);
async Task<IRole> IGuild.CreateRoleAsync(string name, GuildPermissions? permissions, Color? color, bool isHoisted)
=> await CreateRoleAsync(name, permissions, color, isHoisted);
async Task<IReadOnlyCollection<IGuildUser>> IGuild.GetUsersAsync()
=> await GetUsersAsync();
async Task<IGuildUser> IGuild.GetUserAsync(ulong id)
=> await GetUserAsync(id);
IGuildUser IGuild.GetCachedUser(ulong id)
=> null;
async Task<IGuildUser> IGuild.GetCurrentUserAsync()
=> await GetCurrentUserAsync();
async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetUserAsync(id);
else
return null;
}
async Task<IGuildUser> IGuild.GetCurrentUserAsync(CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return await GetCurrentUserAsync();
else
return null;
}
async Task<IReadOnlyCollection<IGuildUser>> IGuild.GetUsersAsync(CacheMode mode)
{
if (mode == CacheMode.AllowDownload)
return (await GetUsersAsync().Flatten()).ToImmutableArray();
else
return ImmutableArray.Create<IGuildUser>();
}
Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); }
}
}

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Model = Discord.API.User;
@@ -42,10 +43,13 @@ namespace Discord.Rest
public virtual async Task UpdateAsync()
=> Update(await UserHelper.GetAsync(this, Discord));
public Task<IDMChannel> CreateDMChannelAsync()
public Task<RestDMChannel> CreateDMChannelAsync()
=> UserHelper.CreateDMChannelAsync(this, Discord);
IDMChannel IUser.GetCachedDMChannel() => null;
Task<IDMChannel> IUser.GetDMChannelAsync(CacheMode mode)
=> Task.FromResult<IDMChannel>(null);
async Task<IDMChannel> IUser.CreateDMChannelAsync()
=> await CreateDMChannelAsync();
}
}

View File

@@ -44,7 +44,7 @@ namespace Discord.Rest
await client.ApiClient.RemoveGuildMemberAsync(user.GuildId, user.Id);
}
public static async Task<IDMChannel> CreateDMChannelAsync(IUser user, BaseDiscordClient client)
public static async Task<RestDMChannel> CreateDMChannelAsync(IUser user, BaseDiscordClient client)
{
var args = new CreateDMChannelParams(user.Id);
return RestDMChannel.Create(client, await client.ApiClient.CreateDMChannelAsync(args));