@@ -9,6 +9,7 @@ using Model = Discord.API.Rpc.Channel; | |||
namespace Discord.Rpc | |||
{ | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RpcDMChannel : RpcChannel, IRpcMessageChannel, IRpcPrivateChannel, IDMChannel | |||
{ | |||
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; } | |||
@@ -10,6 +10,7 @@ using Model = Discord.API.Rpc.Channel; | |||
namespace Discord.Rpc | |||
{ | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RpcGroupChannel : RpcChannel, IRpcMessageChannel, IRpcAudioChannel, IRpcPrivateChannel, IGroupChannel | |||
{ | |||
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; } | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.IO; | |||
namespace Discord.Audio | |||
@@ -7,8 +7,17 @@ namespace Discord.Audio | |||
{ | |||
public override bool CanWrite => true; | |||
public override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } | |||
public override void SetLength(long value) { throw new NotSupportedException(); } | |||
public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Reading this stream is not supported.</exception> | |||
public override int Read(byte[] buffer, int offset, int count) => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Setting the length to this stream is not supported.</exception> | |||
public override void SetLength(long value) => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Seeking this stream is not supported..</exception> | |||
public override long Seek(long offset, SeekOrigin origin) => | |||
throw new NotSupportedException(); | |||
} | |||
} |
@@ -28,17 +28,30 @@ namespace Discord.Audio | |||
public virtual Task ClearAsync(CancellationToken cancellationToken) { return Task.Delay(0); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Reading stream length is not supported.</exception> | |||
public override long Length => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Getting or setting this stream position is not supported.</exception> | |||
public override long Position | |||
{ | |||
get => throw new NotSupportedException(); | |||
set => throw new NotSupportedException(); | |||
} | |||
public override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } | |||
public override void SetLength(long value) { throw new NotSupportedException(); } | |||
public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Reading this stream is not supported.</exception> | |||
public override int Read(byte[] buffer, int offset, int count) => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Setting the length to this stream is not supported.</exception> | |||
public override void SetLength(long value) => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Seeking this stream is not supported..</exception> | |||
public override long Seek(long offset, SeekOrigin origin) => | |||
throw new NotSupportedException(); | |||
} | |||
} |
@@ -41,7 +41,7 @@ namespace Discord | |||
} | |||
/// <summary> Gets or sets the title of an <see cref="Embed"/>. </summary> | |||
/// <exception cref="ArgumentException" accessor="set">Title length exceeds the maximum allowed by Discord. | |||
/// <exception cref="ArgumentException" accessor="set">Title length exceeds <see cref="MaxTitleLength"/>. | |||
/// </exception> | |||
/// <returns> The title of the embed.</returns> | |||
public string Title | |||
@@ -55,7 +55,7 @@ namespace Discord | |||
} | |||
/// <summary> Gets or sets the description of an <see cref="Embed"/>. </summary> | |||
/// <exception cref="ArgumentException" accessor="set">Description length exceeds the maximum allowed by Discord.</exception> | |||
/// <exception cref="ArgumentException" accessor="set">Description length exceeds <see cref="MaxDescriptionLength"/>.</exception> | |||
/// <returns> The description of the embed.</returns> | |||
public string Description | |||
{ | |||
@@ -107,8 +107,8 @@ namespace Discord | |||
/// <summary> Gets or sets the list of <see cref="EmbedFieldBuilder"/> of an <see cref="Embed"/>. </summary> | |||
/// <exception cref="ArgumentNullException" accessor="set">An embed builder's fields collection is set to | |||
/// <see langword="null"/>.</exception> | |||
/// <exception cref="ArgumentException" accessor="set">Description length exceeds the maximum allowed by | |||
/// Discord.</exception> | |||
/// <exception cref="ArgumentException" accessor="set">Description length exceeds <see cref="MaxFieldCount"/>. | |||
/// </exception> | |||
/// <returns> The list of existing <see cref="EmbedFieldBuilder"/>.</returns> | |||
public List<EmbedFieldBuilder> Fields | |||
{ | |||
@@ -282,7 +282,7 @@ namespace Discord | |||
/// <summary> | |||
/// Sets the author field of an <see cref="Embed" /> with the provided properties. | |||
/// </summary> | |||
/// <param name="action">The <see langword="delegate"/> containing the author field properties.</param> | |||
/// <param name="action">The delegate containing the author field properties.</param> | |||
/// <returns> | |||
/// The current builder. | |||
/// </returns> | |||
@@ -328,7 +328,7 @@ namespace Discord | |||
/// <summary> | |||
/// Sets the footer field of an <see cref="Embed" /> with the provided properties. | |||
/// </summary> | |||
/// <param name="action">The <see langword="delegate"/> containing the footer field properties.</param> | |||
/// <param name="action">The delegate containing the footer field properties.</param> | |||
/// <returns> | |||
/// The current builder. | |||
/// </returns> | |||
@@ -382,7 +382,7 @@ namespace Discord | |||
/// <see cref="Embed" />. | |||
/// </summary> | |||
/// <param name="field">The field builder class containing the field properties.</param> | |||
/// <exception cref="ArgumentException">Field count exceeds the maximum allowed by Discord.</exception> | |||
/// <exception cref="ArgumentException">Field count exceeds <see cref="MaxFieldCount"/>.</exception> | |||
/// <returns> | |||
/// The current builder. | |||
/// </returns> | |||
@@ -399,7 +399,7 @@ namespace Discord | |||
/// <summary> | |||
/// Adds an <see cref="Embed" /> field with the provided properties. | |||
/// </summary> | |||
/// <param name="action">The <see langword="delegate"/> containing the field properties.</param> | |||
/// <param name="action">The delegate containing the field properties.</param> | |||
/// <returns> | |||
/// The current builder. | |||
/// </returns> | |||
@@ -417,7 +417,7 @@ namespace Discord | |||
/// <returns> | |||
/// The built embed object. | |||
/// </returns> | |||
/// <exception cref="InvalidOperationException">Total embed length exceeds the maximum allowed by Discord.</exception> | |||
/// <exception cref="InvalidOperationException">Total embed length exceeds <see cref="MaxEmbedLength"/>.</exception> | |||
public Embed Build() | |||
{ | |||
if (Length > MaxEmbedLength) | |||
@@ -542,7 +542,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException"> | |||
/// <para><see cref="Name"/> or <see cref="Value"/> is <see langword="null" />, empty or entirely whitespace.</para> | |||
/// <para><c>- or -</c></para> | |||
/// <para><see cref="Name"/> or <see cref="Value"/> length exceeds the maximum allowed by Discord.</para> | |||
/// <para><see cref="Name"/> or <see cref="Value"/> exceeds the maximum length allowed by Discord.</para> | |||
/// </exception> | |||
public EmbedField Build() | |||
=> new EmbedField(Name, Value.ToString(), IsInline); | |||
@@ -26,8 +26,8 @@ namespace Discord | |||
public Exception Exception { get; } | |||
/// <summary> | |||
/// Initializes a new <see cref="LogMessage" /> <see langword="struct"/> with the severity, source, | |||
/// <paramref name="message"/> of the event, and optionally, an exception. | |||
/// Initializes a new <see cref="LogMessage" /> struct with the severity, source, message of the event, and | |||
/// optionally, an exception. | |||
/// </summary> | |||
/// <param name="severity">The severity of the event.</param> | |||
/// <param name="source">The source of the event.</param> | |||
@@ -11,10 +11,20 @@ namespace Discord.Net | |||
/// <summary> | |||
/// Gets the HTTP status code returned by Discord. | |||
/// </summary> | |||
/// <returns> | |||
/// An | |||
/// <see href="https://discordapp.com/developers/docs/topics/opcodes-and-status-codes#http">HTTP status code</see> | |||
/// from Discord. | |||
/// </returns> | |||
public HttpStatusCode HttpCode { get; } | |||
/// <summary> | |||
/// Gets the JSON error code returned by Discord, or <see langword="null"/> if none. | |||
/// Gets the JSON error code returned by Discord. | |||
/// </summary> | |||
/// <returns> | |||
/// A | |||
/// <see href="https://discordapp.com/developers/docs/topics/opcodes-and-status-codes#json">JSON error code</see> | |||
/// from Discord, or <see langword="null"/> if none. | |||
/// </returns> | |||
public int? DiscordCode { get; } | |||
/// <summary> | |||
/// Gets the reason of the exception. | |||
@@ -2,6 +2,9 @@ using System; | |||
namespace Discord.Net | |||
{ | |||
/// <summary> | |||
/// Represents a generic request to be sent to Discord. | |||
/// </summary> | |||
public interface IRequest | |||
{ | |||
DateTimeOffset? TimeoutAt { get; } | |||
@@ -2,13 +2,18 @@ using System; | |||
namespace Discord.Net | |||
{ | |||
/// <summary> | |||
/// Describes an exception that causes the WebSocket to close during a session. | |||
/// Describes an exception that causes the WebSocket to close during a session. | |||
/// </summary> | |||
public class WebSocketClosedException : Exception | |||
{ | |||
/// <summary> | |||
/// Gets the close code sent by Discord. | |||
/// </summary> | |||
/// <returns> | |||
/// A | |||
/// <see href="https://discordapp.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes">close code</see> | |||
/// from Discord. | |||
/// </returns> | |||
public int CloseCode { get; } | |||
/// <summary> | |||
/// Gets the reason of the interruption. | |||
@@ -16,8 +21,8 @@ namespace Discord.Net | |||
public string Reason { get; } | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="WebSocketClosedException" /> using the Discord close code | |||
/// and the optional reason. | |||
/// Initializes a new instance of the <see cref="WebSocketClosedException" /> using a Discord close code | |||
/// and an optional reason. | |||
/// </summary> | |||
public WebSocketClosedException(int closeCode, string reason = null) | |||
: base($"The server sent close {closeCode}{(reason != null ? $": \"{reason}\"" : "")}") | |||
@@ -4,7 +4,7 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a <see langword="struct"/> that contains an entity that may be cached. | |||
/// Represents a cached entity. | |||
/// </summary> | |||
/// <typeparam name="TEntity">The type of entity that is cached.</typeparam> | |||
/// <typeparam name="TId">The type of this entity's ID.</typeparam> | |||
@@ -25,7 +25,7 @@ namespace Discord | |||
/// </summary> | |||
/// <remarks> | |||
/// This value is not guaranteed to be set; in cases where the entity cannot be pulled from cache, it is | |||
/// null. | |||
/// <see langword="null"/>. | |||
/// </remarks> | |||
public TEntity Value { get; } | |||
private Func<Task<TEntity>> DownloadFunc { get; } | |||
@@ -174,6 +174,7 @@ namespace Discord.Rest | |||
Task<IReadOnlyCollection<IGuild>> IDiscordClient.GetGuildsAsync(CacheMode mode, RequestOptions options) | |||
=> Task.FromResult<IReadOnlyCollection<IGuild>>(ImmutableArray.Create<IGuild>()); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Creating a guild is not supported with the base client.</exception> | |||
Task<IGuild> IDiscordClient.CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
@@ -26,18 +26,30 @@ namespace Discord.Rest | |||
private string DebuggerDisplay => $"{Name} ({Id}, Category)"; | |||
// IGuildChannel | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
//IChannel | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
} | |||
@@ -154,7 +154,10 @@ namespace Discord.Rest | |||
=> EnterTypingState(options); | |||
//IAudioChannel | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) { throw new NotSupportedException(); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Connecting to a group channel is not supported.</exception> | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) => | |||
throw new NotSupportedException(); | |||
//IChannel | |||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
@@ -1,4 +1,4 @@ | |||
using Discord.Audio; | |||
using Discord.Audio; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
@@ -41,7 +41,9 @@ namespace Discord.Rest | |||
private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; | |||
//IAudioChannel | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) { throw new NotSupportedException(); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Connecting to a REST-based channel is not supported.</exception> | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) => throw new NotSupportedException(); | |||
//IGuildChannel | |||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
@@ -1,4 +1,4 @@ | |||
using Discord.Audio; | |||
using Discord.Audio; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -417,7 +417,10 @@ namespace Discord.Rest | |||
else | |||
return ImmutableArray.Create<IGuildUser>(); | |||
} | |||
Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); } | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Downloading users is not supported with a REST-based guild.</exception> | |||
Task IGuild.DownloadUsersAsync() => | |||
throw new NotSupportedException(); | |||
async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options) | |||
=> await GetWebhookAsync(id, options).ConfigureAwait(false); | |||
@@ -8,7 +8,7 @@ namespace Discord.WebSocket | |||
{ | |||
public abstract partial class BaseSocketClient : BaseDiscordClient, IDiscordClient | |||
{ | |||
protected readonly DiscordSocketConfig _baseconfig; | |||
protected readonly DiscordSocketConfig BaseConfig; | |||
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary> | |||
public abstract int Latency { get; protected set; } | |||
@@ -23,7 +23,7 @@ namespace Discord.WebSocket | |||
public abstract IReadOnlyCollection<RestVoiceRegion> VoiceRegions { get; } | |||
internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client) | |||
: base(config, client) => _baseconfig = config; | |||
: base(config, client) => BaseConfig = config; | |||
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) | |||
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent); | |||
@@ -55,8 +55,12 @@ namespace Discord.WebSocket | |||
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable(); | |||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> Task.FromResult<IGuildUser>(GetUser(id)); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
@@ -251,7 +251,9 @@ namespace Discord.WebSocket | |||
//IAudioChannel | |||
/// <inheritdoc /> | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) { throw new NotSupportedException(); } | |||
/// <exception cref="NotSupportedException">Connecting to a group channel is not supported.</exception> | |||
Task<IAudioClient> IAudioChannel.ConnectAsync(Action<IAudioClient> configAction) => | |||
throw new NotSupportedException(); | |||
//IChannel | |||
/// <inheritdoc /> | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Diagnostics; | |||