diff --git a/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs b/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs index 1d36a41b9..d921a2474 100644 --- a/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IVoiceChannel.cs @@ -6,7 +6,7 @@ namespace Discord /// /// Represents a generic voice channel in a guild. /// - public interface IVoiceChannel : INestedChannel, IAudioChannel, IMentionable + public interface IVoiceChannel : IMessageChannel, INestedChannel, IAudioChannel, IMentionable { /// /// Gets the bit-rate that the clients in this voice channel are requested to use. diff --git a/src/Discord.Net.Rest/Entities/Channels/RestStageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestStageChannel.cs index c01df96fd..b34afd027 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestStageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestStageChannel.cs @@ -12,7 +12,11 @@ namespace Discord.Rest public class RestStageChannel : RestVoiceChannel, IStageChannel { /// - public string Topic { get; private set; } + /// + /// This field is always false for stage channels. + /// + public override bool IsTextInVoice + => false; /// public StagePrivacyLevel? PrivacyLevel { get; private set; } @@ -37,13 +41,11 @@ namespace Discord.Rest IsLive = isLive; if(isLive) { - Topic = model.Topic; PrivacyLevel = model.PrivacyLevel; IsDiscoverableDisabled = model.DiscoverableDisabled; } else { - Topic = null; PrivacyLevel = null; IsDiscoverableDisabled = null; } diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 76c75ab6e..a73bda334 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -86,25 +86,25 @@ namespace Discord.Rest => ChannelHelper.GetUsersAsync(this, Guild, Discord, null, null, options); /// - public Task GetMessageAsync(ulong id, RequestOptions options = null) + public virtual Task GetMessageAsync(ulong id, RequestOptions options = null) => ChannelHelper.GetMessageAsync(this, Discord, id, options); /// - public IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options); /// - public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options); /// - public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options); /// - public Task> GetPinnedMessagesAsync(RequestOptions options = null) + public virtual Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, + public virtual Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, @@ -136,7 +136,7 @@ namespace Discord.Rest /// An I/O error occurred while opening the file. /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, + public virtual Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -146,7 +146,7 @@ namespace Discord.Rest /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, + public virtual Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -156,7 +156,7 @@ namespace Discord.Rest /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, + public virtual Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -166,35 +166,35 @@ namespace Discord.Rest /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, + public virtual Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => ChannelHelper.SendFilesAsync(this, Discord, attachments, text, isTTS, embed, allowedMentions, messageReference, components, stickers, options, embeds, flags); /// - public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + public virtual Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); /// - public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + public virtual Task DeleteMessageAsync(IMessage message, RequestOptions options = null) => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); /// - public Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) + public virtual Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options); /// - public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) + public virtual Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messageIds, options); /// - public async Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) + public virtual async Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) => await ChannelHelper.ModifyMessageAsync(this, messageId, func, Discord, options).ConfigureAwait(false); /// - public Task TriggerTypingAsync(RequestOptions options = null) + public virtual Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); /// - public IDisposable EnterTypingState(RequestOptions options = null) + public virtual IDisposable EnterTypingState(RequestOptions options = null) => ChannelHelper.EnterTypingState(this, Discord, options); /// @@ -231,38 +231,6 @@ namespace Discord.Rest public virtual Task> GetWebhooksAsync(RequestOptions options = null) => ChannelHelper.GetWebhooksAsync(this, Discord, options); - /// - /// Gets the parent (category) channel of this channel. - /// - /// The options to be used when sending the request. - /// - /// A task that represents the asynchronous get operation. The task result contains the category channel - /// representing the parent of this channel; null if none is set. - /// - public virtual Task GetCategoryAsync(RequestOptions options = null) - => ChannelHelper.GetCategoryAsync(this, Discord, options); - /// - public Task SyncPermissionsAsync(RequestOptions options = null) - => ChannelHelper.SyncPermissionsAsync(this, Discord, options); - #endregion - - #region Invites - /// - public virtual async Task 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 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); - /// - public virtual async Task 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 CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => throw new NotImplementedException(); - /// - public virtual async Task> GetInvitesAsync(RequestOptions options = null) - => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); - - private string DebuggerDisplay => $"{Name} ({Id}, Text)"; - /// /// Creates a thread within this . /// @@ -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); } + + /// + /// Gets the parent (category) channel of this channel. + /// + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous get operation. The task result contains the category channel + /// representing the parent of this channel; null if none is set. + /// + public virtual Task GetCategoryAsync(RequestOptions options = null) + => ChannelHelper.GetCategoryAsync(this, Discord, options); + /// + public Task SyncPermissionsAsync(RequestOptions options = null) + => ChannelHelper.SyncPermissionsAsync(this, Discord, options); + #endregion + + #region Invites + /// + public virtual async Task 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 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); + /// + public virtual async Task 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 CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) + => throw new NotImplementedException(); + /// + public virtual async Task> GetInvitesAsync(RequestOptions options = null) + => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); + + private string DebuggerDisplay => $"{Name} ({Id}, Text)"; #endregion #region ITextChannel diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs index bcf03a5bc..31d313a48 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs @@ -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,21 @@ namespace Discord.Rest /// Represents a REST-based voice channel in a guild. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] - public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel + public class RestVoiceChannel : RestTextChannel, IVoiceChannel, IRestAudioChannel { #region RestVoiceChannel + /// + /// Gets whether or not the guild has Text-In-Voice enabled and the voice channel is a TiV channel. + /// + public virtual bool IsTextInVoice + => Guild.Features.HasTextInVoice; /// public int Bitrate { get; private set; } /// public int? UserLimit { get; private set; } - /// - public ulong? CategoryId { get; private set; } /// public string RTCRegion { get; private set; } - /// - public string Mention => MentionUtils.MentionChannel(Id); - internal RestVoiceChannel(BaseDiscordClient discord, IGuild guild, ulong id) : base(discord, guild, id) { @@ -41,7 +42,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,41 +59,185 @@ namespace Discord.Rest Update(model); } - /// - /// Gets the parent (category) channel of this channel. - /// - /// The options to be used when sending the request. - /// - /// A task that represents the asynchronous get operation. The task result contains the category channel - /// representing the parent of this channel; null if none is set. - /// - public Task GetCategoryAsync(RequestOptions options = null) - => ChannelHelper.GetCategoryAsync(this, Discord, options); - /// - public Task SyncPermissionsAsync(RequestOptions options = null) - => ChannelHelper.SyncPermissionsAsync(this, Discord, options); - #endregion + /// + /// Cannot modify text channel properties of a voice channel. + public override Task ModifyAsync(Action func, RequestOptions options = null) + => throw new InvalidOperationException("Cannot modify text channel properties of a voice channel"); - #region Invites - /// - public async Task 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 async Task CreateInviteToApplicationAsync(ulong applicationId, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, applicationId, options).ConfigureAwait(false); - /// - public virtual async Task 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 async Task CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => await ChannelHelper.CreateInviteToStreamAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, user, options).ConfigureAwait(false); - /// - public async Task> GetInvitesAsync(RequestOptions options = null) - => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); + /// + /// Cannot create a thread within a voice channel. + public override Task 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"); + + #endregion private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; + + #region TextOverrides + + /// This function is only supported in Text-In-Voice channels. + public override Task GetMessageAsync(ulong id, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessageAsync(id, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessageAsync(message, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessageAsync(messageId, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessagesAsync(messages, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessagesAsync(messageIds, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IDisposable EnterTypingState(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.EnterTypingState(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(fromMessage, dir, limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(fromMessageId, dir, limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task> GetPinnedMessagesAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetPinnedMessagesAsync(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task GetWebhookAsync(ulong id, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetWebhookAsync(id, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task> GetWebhooksAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetWebhooksAsync(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.CreateWebhookAsync(name, avatar, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.ModifyMessageAsync(messageId, func, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(attachment, text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFilesAsync(attachments, text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task TriggerTypingAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.TriggerTypingAsync(options); + } + #endregion + #region IAudioChannel /// /// Connecting to a REST-based channel is not supported. diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs index 79f02fe1c..6d9e759b4 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs @@ -222,6 +222,8 @@ namespace Discord.WebSocket #region IChannel /// + string IChannel.Name => Name; + /// IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => ImmutableArray.Create>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice /// diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketStageChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketStageChannel.cs index 91bca5054..56cd92185 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketStageChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketStageChannel.cs @@ -15,7 +15,11 @@ namespace Discord.WebSocket public class SocketStageChannel : SocketVoiceChannel, IStageChannel { /// - public string Topic { get; private set; } + /// + /// This field is always false for stage channels. + /// + public override bool IsTextInVoice + => false; /// public StagePrivacyLevel? PrivacyLevel { get; private set; } @@ -49,19 +53,16 @@ namespace Discord.WebSocket entity.Update(state, model); return entity; } - internal void Update(StageInstance model, bool isLive = false) { IsLive = isLive; if (isLive) { - Topic = model.Topic; PrivacyLevel = model.PrivacyLevel; IsDiscoverableDisabled = model.DiscoverableDisabled; } else { - Topic = null; PrivacyLevel = null; IsDiscoverableDisabled = null; } diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index e4a299edc..e8454ecf8 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -128,7 +128,7 @@ namespace Discord.WebSocket #region Messages /// - public SocketMessage GetCachedMessage(ulong id) + public virtual SocketMessage GetCachedMessage(ulong id) => _messages?.Get(id); /// /// Gets a message from this message channel. @@ -143,7 +143,7 @@ namespace Discord.WebSocket /// A task that represents an asynchronous get operation for retrieving the message. The task result contains /// the retrieved message; null if no message is found with the specified identifier. /// - public async Task GetMessageAsync(ulong id, RequestOptions options = null) + public virtual async Task GetMessageAsync(ulong id, RequestOptions options = null) { IMessage msg = _messages?.Get(id); if (msg == null) @@ -163,7 +163,7 @@ namespace Discord.WebSocket /// /// Paged collection of messages. /// - public IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, null, Direction.Before, limit, CacheMode.AllowDownload, options); /// /// Gets a collection of messages in this channel. @@ -179,7 +179,7 @@ namespace Discord.WebSocket /// /// Paged collection of messages. /// - public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessageId, dir, limit, CacheMode.AllowDownload, options); /// /// Gets a collection of messages in this channel. @@ -195,25 +195,25 @@ namespace Discord.WebSocket /// /// Paged collection of messages. /// - public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) + public virtual IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, CacheMode.AllowDownload, options); /// - public IReadOnlyCollection GetCachedMessages(int limit = DiscordConfig.MaxMessagesPerBatch) + public virtual IReadOnlyCollection GetCachedMessages(int limit = DiscordConfig.MaxMessagesPerBatch) => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, null, Direction.Before, limit); /// - public IReadOnlyCollection GetCachedMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) + public virtual IReadOnlyCollection GetCachedMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, fromMessageId, dir, limit); /// - public IReadOnlyCollection GetCachedMessages(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) + public virtual IReadOnlyCollection GetCachedMessages(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, fromMessage.Id, dir, limit); /// - public Task> GetPinnedMessagesAsync(RequestOptions options = null) + public virtual Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, + public virtual Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, @@ -221,7 +221,7 @@ namespace Discord.WebSocket /// /// The only valid are and . - public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, + public virtual Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -230,7 +230,7 @@ namespace Discord.WebSocket /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, + public virtual Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -239,7 +239,7 @@ namespace Discord.WebSocket /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, + public virtual Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -248,7 +248,7 @@ namespace Discord.WebSocket /// /// Message content is too long, length must be less or equal to . /// The only valid are and . - public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, + public virtual Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) @@ -256,28 +256,28 @@ namespace Discord.WebSocket messageReference, components, stickers, options, embeds, flags); /// - public Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) + public virtual Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options); /// - public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) + public virtual Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messageIds, options); /// - public async Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) + public virtual async Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) => await ChannelHelper.ModifyMessageAsync(this, messageId, func, Discord, options).ConfigureAwait(false); /// - public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + public virtual Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); /// - public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + public virtual Task DeleteMessageAsync(IMessage message, RequestOptions options = null) => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); /// - public Task TriggerTypingAsync(RequestOptions options = null) + public virtual Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); /// - public IDisposable EnterTypingState(RequestOptions options = null) + public virtual IDisposable EnterTypingState(RequestOptions options = null) => ChannelHelper.EnterTypingState(this, Discord, options); internal void AddMessage(SocketMessage msg) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs index 00003d4ed..5fc99c3f1 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs @@ -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,33 +15,21 @@ namespace Discord.WebSocket /// Represents a WebSocket-based voice channel in a guild. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] - public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel + public class SocketVoiceChannel : SocketTextChannel, IVoiceChannel, ISocketAudioChannel { #region SocketVoiceChannel - /// - public int Bitrate { get; private set; } - /// - public int? UserLimit { get; private set; } - /// - public string RTCRegion { get; private set; } - - /// - public ulong? CategoryId { get; private set; } /// - /// Gets the parent (category) channel of this channel. + /// Gets whether or not the guild has Text-In-Voice enabled and the voice channel is a TiV channel. /// - /// - /// A category channel representing the parent of this channel; null if none is set. - /// - public ICategoryChannel Category - => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null; + public virtual bool IsTextInVoice + => Guild.Features.HasTextInVoice; /// - public string Mention => MentionUtils.MentionChannel(Id); - + public int Bitrate { get; private set; } + /// + public int? UserLimit { get; private set; } /// - public Task SyncPermissionsAsync(RequestOptions options = null) - => ChannelHelper.SyncPermissionsAsync(this, Discord, options); + public string RTCRegion { get; private set; } /// /// Gets a collection of users that are currently connected to this voice channel. @@ -48,7 +37,7 @@ namespace Discord.WebSocket /// /// A read-only collection of users that are currently connected to this voice channel. /// - public override IReadOnlyCollection Users + public IReadOnlyCollection ConnectedUsers => Guild.Users.Where(x => x.VoiceChannel?.Id == Id).ToImmutableArray(); internal SocketVoiceChannel(DiscordSocketClient discord, ulong id, SocketGuild guild) @@ -65,7 +54,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,28 +87,215 @@ namespace Discord.WebSocket return user; return null; } -#endregion - #region Invites - /// - public async Task 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 async Task CreateInviteToApplicationAsync(ulong applicationId, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => await ChannelHelper.CreateInviteToApplicationAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, applicationId, options).ConfigureAwait(false); - /// - public virtual async Task 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 async Task CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => await ChannelHelper.CreateInviteToStreamAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, user, options).ConfigureAwait(false); - /// - public async Task> GetInvitesAsync(RequestOptions options = null) - => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); + /// Cannot create threads in voice channels. + public override Task 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."); + + /// Cannot modify text channel properties for voice channels. + public override Task ModifyAsync(Action func, RequestOptions options = null) + => throw new InvalidOperationException("Cannot modify text channel properties for voice channels."); + + #endregion + + #region TextOverrides + + /// This function is only supported in Text-In-Voice channels. + public override Task GetMessageAsync(ulong id, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessageAsync(id, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessageAsync(message, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessageAsync(messageId, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessagesAsync(messages, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.DeleteMessagesAsync(messageIds, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IDisposable EnterTypingState(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.EnterTypingState(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override SocketMessage GetCachedMessage(ulong id) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetCachedMessage(id); + } + + /// This function is only supported in Text-In-Voice channels. + public override IReadOnlyCollection GetCachedMessages(IMessage fromMessage, Direction dir, int limit = 100) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetCachedMessages(fromMessage, dir, limit); + } + + /// This function is only supported in Text-In-Voice channels. + public override IReadOnlyCollection GetCachedMessages(int limit = 100) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetCachedMessages(limit); + } + + /// This function is only supported in Text-In-Voice channels. + public override IReadOnlyCollection GetCachedMessages(ulong fromMessageId, Direction dir, int limit = 100) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetCachedMessages(fromMessageId, dir, limit); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(fromMessage, dir, limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetMessagesAsync(fromMessageId, dir, limit, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task> GetPinnedMessagesAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetPinnedMessagesAsync(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task GetWebhookAsync(ulong id, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetWebhookAsync(id, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task> GetWebhooksAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.GetWebhooksAsync(options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.CreateWebhookAsync(name, avatar, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.ModifyMessageAsync(messageId, func, options); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(attachment, text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendFilesAsync(attachments, text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, components, stickers, embeds, flags); + } + + /// This function is only supported in Text-In-Voice channels. + public override Task TriggerTypingAsync(RequestOptions options = null) + { + if (!IsTextInVoice) + throw new NotSupportedException("This function is only supported in Text-In-Voice channels"); + return base.TriggerTypingAsync(options); + } + + #endregion private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; internal new SocketVoiceChannel Clone() => MemberwiseClone() as SocketVoiceChannel; - #endregion #region IGuildChannel /// diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs index 533b1b1b5..fdbdeda5e 100644 --- a/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using System.Threading.Tasks; using Discord.Audio; @@ -12,8 +13,6 @@ namespace Discord public int? UserLimit => throw new NotImplementedException(); - public string Mention => throw new NotImplementedException(); - public ulong? CategoryId => throw new NotImplementedException(); public int Position => throw new NotImplementedException(); @@ -24,116 +23,53 @@ namespace Discord public IReadOnlyCollection PermissionOverwrites => throw new NotImplementedException(); + public string RTCRegion => throw new NotImplementedException(); + public string Name => throw new NotImplementedException(); public DateTimeOffset CreatedAt => throw new NotImplementedException(); - public ulong Id => throw new NotImplementedException(); - - public string RTCRegion => throw new NotImplementedException(); - public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) - { - throw new NotImplementedException(); - } + public ulong Id => throw new NotImplementedException(); - public Task ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false) - { - throw new NotImplementedException(); - } + public string Mention => throw new NotImplementedException(); - public Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - { - throw new NotImplementedException(); - } - public Task CreateInviteToApplicationAsync(ulong applicationId, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => throw new NotImplementedException(); + public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) => throw new NotImplementedException(); + public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) => throw new NotImplementedException(); + public Task ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false) => throw new NotImplementedException(); + public Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => throw new NotImplementedException(); + public Task CreateInviteToApplicationAsync(ulong applicationId, int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => throw new NotImplementedException(); public Task CreateInviteToApplicationAsync(DefaultApplications application, int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => throw new NotImplementedException(); - public Task CreateInviteToStreamAsync(IUser user, int? maxAge, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null) - => throw new NotImplementedException(); - - public Task DeleteAsync(RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task DisconnectAsync() - { - throw new NotImplementedException(); - } - - public Task ModifyAsync(Action func, RequestOptions options) - { - throw new NotImplementedException(); - } - - public Task GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task> GetInvitesAsync(RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public OverwritePermissions? GetPermissionOverwrite(IRole role) - { - throw new NotImplementedException(); - } - - public OverwritePermissions? GetPermissionOverwrite(IUser user) - { - throw new NotImplementedException(); - } - - public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task ModifyAsync(Action func, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task ModifyAsync(Action func, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) - { - throw new NotImplementedException(); - } - - public Task SyncPermissionsAsync(RequestOptions options = null) - { - throw new NotImplementedException(); - } - - Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) - { - throw new NotImplementedException(); - } - - IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) - { - throw new NotImplementedException(); - } + public Task CreateInviteToStreamAsync(IUser user, int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => throw new NotImplementedException(); + public Task DeleteAsync(RequestOptions options = null) => 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(); + public IDisposable EnterTypingState(RequestOptions options = null) => throw new NotImplementedException(); + public Task GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public Task> GetInvitesAsync(RequestOptions options = null) => throw new NotImplementedException(); + public Task GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public IAsyncEnumerable> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public IAsyncEnumerable> 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(); + public OverwritePermissions? GetPermissionOverwrite(IUser user) => throw new NotImplementedException(); + public Task> GetPinnedMessagesAsync(RequestOptions options = null) => throw new NotImplementedException(); + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) => throw new NotImplementedException(); + public Task ModifyAsync(Action func, RequestOptions options = null) => throw new NotImplementedException(); + public Task ModifyAsync(Action func, RequestOptions options = null) => throw new NotImplementedException(); + public Task ModifyAsync(Action func, RequestOptions options = null) => throw new NotImplementedException(); + public Task ModifyMessageAsync(ulong messageId, Action func, RequestOptions options = null) => throw new NotImplementedException(); + public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) => throw new NotImplementedException(); + public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) => throw new NotImplementedException(); + public Task 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 components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); + public Task 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 components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); + public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); + public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); + public Task SyncPermissionsAsync(RequestOptions options = null) => throw new NotImplementedException(); + public Task TriggerTypingAsync(RequestOptions options = null) => throw new NotImplementedException(); + Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) => throw new NotImplementedException(); + IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => throw new NotImplementedException(); } }