Browse Source

Initial implementation

pull/2269/head
Quin Lynch 3 years ago
parent
commit
585702ac4b
6 changed files with 107 additions and 57 deletions
  1. +1
    -1
      src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs
  2. +32
    -32
      src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
  3. +27
    -20
      src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
  4. +2
    -0
      src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
  5. +25
    -4
      src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
  6. +20
    -0
      test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs

+ 1
- 1
src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs View File

@@ -6,7 +6,7 @@ namespace Discord
/// <summary>
/// Represents a generic voice channel in a guild.
/// </summary>
public interface IVoiceChannel : INestedChannel, IAudioChannel, IMentionable
public interface IVoiceChannel : IMessageChannel, INestedChannel, IAudioChannel, IMentionable
{
/// <summary>
/// Gets the bit-rate that the clients in this voice channel are requested to use.


+ 32
- 32
src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs View File

@@ -231,38 +231,6 @@ namespace Discord.Rest
public virtual Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> ChannelHelper.GetWebhooksAsync(this, Discord, options);

/// <summary>
/// Gets the parent (category) channel of this channel.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the category channel
/// representing the parent of this channel; <c>null</c> if none is set.
/// </returns>
public virtual Task<ICategoryChannel> GetCategoryAsync(RequestOptions options = null)
=> ChannelHelper.GetCategoryAsync(this, Discord, options);
/// <inheritdoc />
public Task SyncPermissionsAsync(RequestOptions options = null)
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options);
#endregion

#region Invites
/// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
public virtual async Task<IInviteMetadata> CreateInviteToApplicationAsync(ulong applicationId, int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, applicationId, options);
/// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteToApplicationAsync(DefaultApplications application, int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, (ulong)application, options);
public virtual Task<IInviteMetadata> CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> throw new NotImplementedException();
/// <inheritdoc />
public virtual async Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);

private string DebuggerDisplay => $"{Name} ({Id}, Text)";

/// <summary>
/// Creates a thread within this <see cref="ITextChannel"/>.
/// </summary>
@@ -299,6 +267,38 @@ namespace Discord.Rest
var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, invitable, slowmode, options);
return RestThreadChannel.Create(Discord, Guild, model);
}

/// <summary>
/// Gets the parent (category) channel of this channel.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the category channel
/// representing the parent of this channel; <c>null</c> if none is set.
/// </returns>
public virtual Task<ICategoryChannel> GetCategoryAsync(RequestOptions options = null)
=> ChannelHelper.GetCategoryAsync(this, Discord, options);
/// <inheritdoc />
public Task SyncPermissionsAsync(RequestOptions options = null)
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options);
#endregion

#region Invites
/// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
public virtual async Task<IInviteMetadata> CreateInviteToApplicationAsync(ulong applicationId, int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, applicationId, options);
/// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteToApplicationAsync(DefaultApplications application, int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, (ulong)application, options);
public virtual Task<IInviteMetadata> CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> throw new NotImplementedException();
/// <inheritdoc />
public virtual async Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);

private string DebuggerDisplay => $"{Name} ({Id}, Text)";
#endregion

#region ITextChannel


+ 27
- 20
src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs View File

@@ -2,6 +2,7 @@ using Discord.Audio;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Channel;
@@ -12,21 +13,16 @@ namespace Discord.Rest
/// Represents a REST-based voice channel in a guild.
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel
public class RestVoiceChannel : RestTextChannel, IVoiceChannel, IRestAudioChannel
{
#region RestVoiceChannel
/// <inheritdoc />
public int Bitrate { get; private set; }
/// <inheritdoc />
public int? UserLimit { get; private set; }
/// <inheritdoc />
public ulong? CategoryId { get; private set; }
/// <inheritdoc/>
public string RTCRegion { get; private set; }

/// <inheritdoc />
public string Mention => MentionUtils.MentionChannel(Id);

internal RestVoiceChannel(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id)
{
@@ -41,7 +37,6 @@ namespace Discord.Rest
internal override void Update(Model model)
{
base.Update(model);
CategoryId = model.CategoryId;

if(model.Bitrate.IsSpecified)
Bitrate = model.Bitrate.Value;
@@ -59,19 +54,31 @@ namespace Discord.Rest
Update(model);
}

/// <summary>
/// Gets the parent (category) channel of this channel.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the category channel
/// representing the parent of this channel; <c>null</c> if none is set.
/// </returns>
public Task<ICategoryChannel> GetCategoryAsync(RequestOptions options = null)
=> ChannelHelper.GetCategoryAsync(this, Discord, options);
/// <inheritdoc />
public Task SyncPermissionsAsync(RequestOptions options = null)
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options);
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot modify text channel properties of a voice channel.</exception>
public override Task ModifyAsync(Action<TextChannelProperties> func, RequestOptions options = null)
=> throw new InvalidOperationException("Cannot modify text channel properties of a voice channel");

/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot create a thread within a voice channel.</exception>
public override Task<RestThreadChannel> CreateThreadAsync(string name, ThreadType type = ThreadType.PublicThread, ThreadArchiveDuration autoArchiveDuration = ThreadArchiveDuration.OneDay, IMessage message = null, bool? invitable = null, int? slowmode = null, RequestOptions options = null)
=> throw new InvalidOperationException("Cannot create a thread within a voice channel");

/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot create a webhook within a voice channel.</exception>
public override Task<RestWebhook> CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null)
=> throw new InvalidOperationException();

/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot get webhooks for a voice channel.</exception>
public override Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
=> throw new InvalidOperationException();

/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot get webhooks for a voice channel.</exception>
public override Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> throw new InvalidOperationException();

#endregion

#region Invites


+ 2
- 0
src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs View File

@@ -222,6 +222,8 @@ namespace Discord.WebSocket

#region IChannel
/// <inheritdoc />
string IChannel.Name => Name;
/// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice
/// <inheritdoc />


+ 25
- 4
src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs View File

@@ -4,6 +4,7 @@ using System;
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;
@@ -14,7 +15,7 @@ namespace Discord.WebSocket
/// Represents a WebSocket-based voice channel in a guild.
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel
public class SocketVoiceChannel : SocketTextChannel, IVoiceChannel, ISocketAudioChannel
{
#region SocketVoiceChannel
/// <inheritdoc />
@@ -48,7 +49,7 @@ namespace Discord.WebSocket
/// <returns>
/// A read-only collection of users that are currently connected to this voice channel.
/// </returns>
public override IReadOnlyCollection<SocketGuildUser> Users
public IReadOnlyCollection<SocketGuildUser> ConnectedUsers
=> Guild.Users.Where(x => x.VoiceChannel?.Id == Id).ToImmutableArray();

internal SocketVoiceChannel(DiscordSocketClient discord, ulong id, SocketGuild guild)
@@ -65,7 +66,6 @@ namespace Discord.WebSocket
internal override void Update(ClientState state, Model model)
{
base.Update(state, model);
CategoryId = model.CategoryId;
Bitrate = model.Bitrate.Value;
UserLimit = model.UserLimit.Value != 0 ? model.UserLimit.Value : (int?)null;
RTCRegion = model.RTCRegion.GetValueOrDefault(null);
@@ -99,7 +99,28 @@ namespace Discord.WebSocket
return user;
return null;
}
#endregion

/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot create threads in voice channels.</exception>
public override Task<SocketThreadChannel> CreateThreadAsync(string name, ThreadType type = ThreadType.PublicThread, ThreadArchiveDuration autoArchiveDuration = ThreadArchiveDuration.OneDay, IMessage message = null, bool? invitable = null, int? slowmode = null, RequestOptions options = null)
=> throw new InvalidOperationException("Voice channels cannot contain threads.");
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot create webhooks in voice channels.</exception>
public override Task<RestWebhook> CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null)
=> throw new InvalidOperationException("Voice channels cannot contain webhooks.");
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot modify text channel properties within a webhook.</exception>
public override Task ModifyAsync(Action<TextChannelProperties> func, RequestOptions options = null)
=> throw new InvalidOperationException("Cannot modify text channel properties for voice channels.");
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot get webhooks for a voice channel.</exception>
public override Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
=> throw new InvalidOperationException("Cannot get webhooks for a voice channel.");
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">Cannot get webhooks for a voice channel.</exception>
public override Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> throw new InvalidOperationException("Cannot get webhooks for a voice channel.");
#endregion

#region Invites
/// <inheritdoc />


+ 20
- 0
test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Discord.Audio;
@@ -61,6 +62,9 @@ namespace Discord
throw new NotImplementedException();
}

public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) => throw new NotImplementedException();
public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) => throw new NotImplementedException();

public Task DisconnectAsync()
{
throw new NotImplementedException();
@@ -70,6 +74,7 @@ namespace Discord
{
throw new NotImplementedException();
}
public IDisposable EnterTypingState(RequestOptions options = null) => throw new NotImplementedException();

public Task<ICategoryChannel> GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
{
@@ -81,6 +86,11 @@ namespace Discord
throw new NotImplementedException();
}

public Task<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException();
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException();
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException();
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException();

public OverwritePermissions? GetPermissionOverwrite(IRole role)
{
throw new NotImplementedException();
@@ -91,6 +101,8 @@ namespace Discord
throw new NotImplementedException();
}

public Task<IReadOnlyCollection<IMessage>> GetPinnedMessagesAsync(RequestOptions options = null) => throw new NotImplementedException();

public Task<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
{
throw new NotImplementedException();
@@ -111,6 +123,8 @@ namespace Discord
throw new NotImplementedException();
}

public Task<IUserMessage> ModifyMessageAsync(ulong messageId, Action<MessageProperties> func, RequestOptions options = null) => throw new NotImplementedException();

public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null)
{
throw new NotImplementedException();
@@ -121,11 +135,17 @@ namespace Discord
throw new NotImplementedException();
}

public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null, Embed[] embeds = null) => throw new NotImplementedException();
public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null, Embed[] embeds = null) => throw new NotImplementedException();
public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null, Embed[] embeds = null) => throw new NotImplementedException();

public Task SyncPermissionsAsync(RequestOptions options = null)
{
throw new NotImplementedException();
}

public Task TriggerTypingAsync(RequestOptions options = null) => throw new NotImplementedException();

Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
throw new NotImplementedException();


Loading…
Cancel
Save