| @@ -8,13 +8,26 @@ namespace Discord | |||
| public static class CDN | |||
| { | |||
| /// <summary> | |||
| /// Returns the Discord developer application icon. | |||
| /// Returns an application icon URL. | |||
| /// </summary> | |||
| /// <param name="appId">The application identifier.</param> | |||
| /// <param name="iconId">The icon identifier.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the application's icon. | |||
| /// </returns> | |||
| public static string GetApplicationIconUrl(ulong appId, string iconId) | |||
| => iconId != null ? $"{DiscordConfig.CDNUrl}app-icons/{appId}/{iconId}.jpg" : null; | |||
| /// <summary> | |||
| /// Returns the user avatar URL based on the <paramref name="size"/> and <see cref="ImageFormat" />. | |||
| /// Returns a user avatar URL. | |||
| /// </summary> | |||
| /// <param name="userId">The user snowflake identifier.</param> | |||
| /// <param name="avatarId">The avatar identifier.</param> | |||
| /// <param name="size">The size of the image to return in. This can be any power of two between 16 and 2048.</param> | |||
| /// <param name="format">The format to return.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the user's avatar in the specified size. | |||
| /// </returns> | |||
| public static string GetUserAvatarUrl(ulong userId, string avatarId, ushort size, ImageFormat format) | |||
| { | |||
| if (avatarId == null) | |||
| @@ -26,34 +39,64 @@ namespace Discord | |||
| /// Returns the default user avatar URL. | |||
| /// </summary> | |||
| /// <param name="discriminator">The discriminator value of a user.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the user's default avatar when one isn't set. | |||
| /// </returns> | |||
| public static string GetDefaultUserAvatarUrl(ushort discriminator) | |||
| { | |||
| return $"{DiscordConfig.CDNUrl}embed/avatars/{discriminator % 5}.png"; | |||
| } | |||
| /// <summary> | |||
| /// Returns the icon URL associated with the given guild ID. | |||
| /// Returns an icon URL. | |||
| /// </summary> | |||
| /// <param name="guildId">The guild snowflake identifier.</param> | |||
| /// <param name="iconId">The icon identifier.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the guild's icon. | |||
| /// </returns> | |||
| public static string GetGuildIconUrl(ulong guildId, string iconId) | |||
| => iconId != null ? $"{DiscordConfig.CDNUrl}icons/{guildId}/{iconId}.jpg" : null; | |||
| /// <summary> | |||
| /// Returns the guild splash URL associated with the given guild and splash ID. | |||
| /// Returns a guild splash URL. | |||
| /// </summary> | |||
| /// <param name="guildId">The guild snowflake identifier.</param> | |||
| /// <param name="splashId">The splash icon identifier.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the guild's icon. | |||
| /// </returns> | |||
| public static string GetGuildSplashUrl(ulong guildId, string splashId) | |||
| => splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null; | |||
| /// <summary> | |||
| /// Returns the channel icon URL associated with the given guild and icon ID. | |||
| /// Returns a channel icon URL. | |||
| /// </summary> | |||
| /// <param name="channelId">The channel snowflake identifier.</param> | |||
| /// <param name="iconId">The icon identifier.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the channel's icon. | |||
| /// </returns> | |||
| public static string GetChannelIconUrl(ulong channelId, string iconId) | |||
| => iconId != null ? $"{DiscordConfig.CDNUrl}channel-icons/{channelId}/{iconId}.jpg" : null; | |||
| /// <summary> | |||
| /// Returns the emoji URL based on the emoji ID. | |||
| /// Returns an emoji URL. | |||
| /// </summary> | |||
| /// <param name="emojiId">The emoji snowflake identifier.</param> | |||
| /// <param name="animated">Whether this emoji is animated.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the custom emote. | |||
| /// </returns> | |||
| public static string GetEmojiUrl(ulong emojiId, bool animated) | |||
| => $"{DiscordConfig.CDNUrl}emojis/{emojiId}.{(animated ? "gif" : "png")}"; | |||
| /// <summary> | |||
| /// Returns the rich presence asset URL based on the asset ID and <see cref="ImageFormat" />. | |||
| /// Returns a Rich Presence asset URL. | |||
| /// </summary> | |||
| /// <param name="appId">The application identifier.</param> | |||
| /// <param name="assetId">The asset identifier.</param> | |||
| /// <param name="size">The size of the image to return in. This can be any power of two between 16 and 2048.</param> | |||
| /// <param name="format">The format to return.</param> | |||
| /// <returns> | |||
| /// A URL pointing to the asset image in the specified size. | |||
| /// </returns> | |||
| public static string GetRichAssetUrl(ulong appId, string assetId, ushort size, ImageFormat format) | |||
| { | |||
| string extension = FormatToExtension(format, ""); | |||
| @@ -61,10 +104,21 @@ namespace Discord | |||
| } | |||
| /// <summary> | |||
| /// Returns the Spotify album URL based on the album art ID. | |||
| /// Returns a Spotify album URL. | |||
| /// </summary> | |||
| /// <param name="albumArtId">The identifier for the album art (e.g. 6be8f4c8614ecf4f1dd3ebba8d8692d8ce4951ac).</param> | |||
| /// <returns> | |||
| /// A URL pointing to the Spotify album art. | |||
| /// </returns> | |||
| public static string GetSpotifyAlbumArtUrl(string albumArtId) | |||
| => $"https://i.scdn.co/image/{albumArtId}"; | |||
| /// <summary> | |||
| /// Returns a Spotify direct URL for a track. | |||
| /// </summary> | |||
| /// <param name="trackId">The identifier for the track (e.g. 4uLU6hMCjMI75M1A2tKUQC).</param> | |||
| /// <returns> | |||
| /// A URL pointing to the Spotify track. | |||
| /// </returns> | |||
| public static string GetSpotifyDirectUrl(string trackId) | |||
| => $"https://open.spotify.com/track/{trackId}"; | |||
| @@ -8,12 +8,22 @@ namespace Discord | |||
| public class DiscordConfig | |||
| { | |||
| /// <summary> | |||
| /// Returns the gateway version Discord.Net uses. | |||
| /// Returns the API version Discord.Net uses. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A 32-bit integer representing the API version that Discord.Net uses to communicate with Discord. | |||
| /// <para>A list of available API version can be seen on the official | |||
| /// <see href="https://discordapp.com/developers/docs/reference#api-versioning">Discord API documentation</see> | |||
| /// .</para> | |||
| /// </returns> | |||
| public const int APIVersion = 6; | |||
| /// <summary> | |||
| /// Gets the Discord.Net version, including the build number. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the detailed version information, including its build number; <c>Unknown</c> when | |||
| /// the version fails to be fetched. | |||
| /// </returns> | |||
| public static string Version { get; } = | |||
| typeof(DiscordConfig).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? | |||
| typeof(DiscordConfig).GetTypeInfo().Assembly.GetName().Version.ToString(3) ?? | |||
| @@ -22,54 +32,91 @@ namespace Discord | |||
| /// <summary> | |||
| /// Gets the user agent that Discord.Net uses in its clients. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The user agent used in each Discord.Net request. | |||
| /// </returns> | |||
| public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})"; | |||
| /// <summary> | |||
| /// Returns the base Discord API URL. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The Discord API URL using <see cref="APIVersion"/>. | |||
| /// </returns> | |||
| public static readonly string APIUrl = $"https://discordapp.com/api/v{APIVersion}/"; | |||
| /// <summary> | |||
| /// Returns the base Discord CDN URL. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The base Discord Content Delivery Network (CDN) URL. | |||
| /// </returns> | |||
| public const string CDNUrl = "https://cdn.discordapp.com/"; | |||
| /// <summary> | |||
| /// Returns the base Discord invite URL. | |||
| /// Returns the base Discord invite URL. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The base Discord invite URL. | |||
| /// </returns> | |||
| public const string InviteUrl = "https://discord.gg/"; | |||
| /// <summary> | |||
| /// Returns the default timeout for requests. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The amount of time it takes in milliseconds before a request is timed out. | |||
| /// </returns> | |||
| public const int DefaultRequestTimeout = 15000; | |||
| /// <summary> | |||
| /// Returns the max length for a Discord message. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The maximum length of a message allowed by Discord. | |||
| /// </returns> | |||
| public const int MaxMessageSize = 2000; | |||
| /// <summary> | |||
| /// Returns the max messages allowed to be in a request. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The maximum number of messages that can be gotten per-batch. | |||
| /// </returns> | |||
| public const int MaxMessagesPerBatch = 100; | |||
| /// <summary> | |||
| /// Returns the max users allowed to be in a request. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The maximum number of users that can be gotten per-batch. | |||
| /// </returns> | |||
| public const int MaxUsersPerBatch = 1000; | |||
| /// <summary> | |||
| /// Returns the max guilds allowed to be in a request. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The maximum number of guilds that can be gotten per-batch. | |||
| /// </returns> | |||
| public const int MaxGuildsPerBatch = 100; | |||
| /// <summary> | |||
| /// Gets or sets how a request should act in the case of an error, by default. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The currently set <see cref="RetryMode"/>. | |||
| /// </returns> | |||
| public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry; | |||
| /// <summary> | |||
| /// Gets or sets the minimum log level severity that will be sent to the Log event. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The currently set <see cref="LogSeverity"/> for logging level. | |||
| /// </returns> | |||
| public LogSeverity LogLevel { get; set; } = LogSeverity.Info; | |||
| /// <summary> | |||
| /// Gets or sets whether the initial log entry should be printed. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If set to <c>true</c>, the library will attempt to print the current version of the library, as well as | |||
| /// the API version it uses on startup. | |||
| /// </remarks> | |||
| internal bool DisplayInitialLog { get; set; } = true; | |||
| } | |||
| } | |||
| @@ -6,33 +6,54 @@ namespace Discord | |||
| public interface IAttachment | |||
| { | |||
| /// <summary> | |||
| /// Gets the snowflake ID of the attachment. | |||
| /// Gets the ID of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A snowflake ID associated with this attachment. | |||
| /// </returns> | |||
| ulong Id { get; } | |||
| /// <summary> | |||
| /// Gets the filename of the attachment. | |||
| /// Gets the filename of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the full filename of this attachment (e.g. textFile.txt). | |||
| /// </returns> | |||
| string Filename { get; } | |||
| /// <summary> | |||
| /// Gets the URL of the attachment. | |||
| /// Gets the URL of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the URL of this attachment. | |||
| /// </returns> | |||
| string Url { get; } | |||
| /// <summary> | |||
| /// Gets the proxied URL of the attachment. | |||
| /// Gets a proxied URL of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the proxied URL of this attachment. | |||
| /// </returns> | |||
| string ProxyUrl { get; } | |||
| /// <summary> | |||
| /// Gets the file size of the attachment. | |||
| /// Gets the file size of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The size of this attachment in bytes. | |||
| /// </returns> | |||
| int Size { get; } | |||
| /// <summary> | |||
| /// Gets the height of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
| /// Gets the height of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The height of this attachment if it is a picture; otherwise <see langword="null"/>. | |||
| /// </returns> | |||
| int? Height { get; } | |||
| /// <summary> | |||
| /// Gets the width of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
| /// Gets the width of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The width of this attachment if it is a picture; otherwise <see langword="null"/>. | |||
| /// </returns> | |||
| int? Width { get; } | |||
| } | |||
| } | |||
| @@ -9,56 +9,96 @@ namespace Discord | |||
| public interface IEmbed | |||
| { | |||
| /// <summary> | |||
| /// Gets the title URL of the embed. | |||
| /// Gets the title URL of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the URL set in a title of the embed. | |||
| /// </returns> | |||
| string Url { get; } | |||
| /// <summary> | |||
| /// Gets the title of the embed. | |||
| /// Gets the title of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The title of the embed. | |||
| /// </returns> | |||
| string Title { get; } | |||
| /// <summary> | |||
| /// Gets the description of the embed. | |||
| /// Gets the description of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The description field of the embed. | |||
| /// </returns> | |||
| string Description { get; } | |||
| /// <summary> | |||
| /// Gets the type of the embed. | |||
| /// Gets the type of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The type of the embed. | |||
| /// </returns> | |||
| EmbedType Type { get; } | |||
| /// <summary> | |||
| /// Gets the timestamp of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the timestamp of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A <see cref="DateTimeOffset"/> based on the timestamp present at the bottom left of the embed, or | |||
| /// <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| DateTimeOffset? Timestamp { get; } | |||
| /// <summary> | |||
| /// Gets the sidebar color of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the color of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The color of the embed present on the side of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| Color? Color { get; } | |||
| /// <summary> | |||
| /// Gets the image of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the image of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The image of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedImage? Image { get; } | |||
| /// <summary> | |||
| /// Gets the video of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the video of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The video of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedVideo? Video { get; } | |||
| /// <summary> | |||
| /// Gets the author field of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the author field of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The author field of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedAuthor? Author { get; } | |||
| /// <summary> | |||
| /// Gets the footer field of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the footer field of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The author field of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedFooter? Footer { get; } | |||
| /// <summary> | |||
| /// Gets the provider of the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the provider of this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The source of the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedProvider? Provider { get; } | |||
| /// <summary> | |||
| /// Gets the thumbnail featured in the embed, or <see langword="null" /> if none is set. | |||
| /// Gets the thumbnail featured in this embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// The thumbnail featured in the embed, or <see langword="null" /> if none is set. | |||
| /// </returns> | |||
| EmbedThumbnail? Thumbnail { get; } | |||
| /// <summary> | |||
| /// Gets the fields of the embed. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// An array of the fields of the embed. | |||
| /// </returns> | |||
| ImmutableArray<EmbedField> Fields { get; } | |||
| } | |||
| } | |||
| @@ -4,7 +4,7 @@ using System.Diagnostics; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Represents a Discord color. | |||
| /// Represents a color used in Discord. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public struct Color | |||
| @@ -65,7 +65,7 @@ namespace Discord | |||
| /// <summary> | |||
| /// Initializes a <see cref="Color" /> struct with the given raw value. | |||
| /// </summary> | |||
| /// <param name="rawValue">A raw value for the color (e.g. <c>0x607D8B</c>).</param> | |||
| /// <param name="rawValue">The raw value of the color (e.g. <c>0x607D8B</c>).</param> | |||
| public Color(uint rawValue) | |||
| { | |||
| RawValue = rawValue; | |||
| @@ -73,9 +73,9 @@ namespace Discord | |||
| /// <summary> | |||
| /// Initializes a <see cref="Color" /> struct with the given RGB bytes. | |||
| /// </summary> | |||
| /// <param name="r">The <see langword="byte"/> that represents the red color.</param> | |||
| /// <param name="g">The <see langword="byte"/> that represents the green color.</param> | |||
| /// <param name="b">The <see langword="byte"/> that represents the blue color.</param> | |||
| /// <param name="r">The byte that represents the red color.</param> | |||
| /// <param name="g">The byte that represents the green color.</param> | |||
| /// <param name="b">The byte that represents the blue color.</param> | |||
| public Color(byte r, byte g, byte b) | |||
| { | |||
| RawValue = | |||
| @@ -126,8 +126,11 @@ namespace Discord | |||
| } | |||
| /// <summary> | |||
| /// Gets the hexadecimal representation of the color (e.g. #000ccc). | |||
| /// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>). | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A hexadecimal string of the color. | |||
| /// </returns> | |||
| public override string ToString() => | |||
| $"#{Convert.ToString(RawValue, 16)}"; | |||
| private string DebuggerDisplay => | |||
| @@ -12,11 +12,11 @@ namespace Discord | |||
| /// </summary> | |||
| string AvatarId { get; } | |||
| /// <summary> | |||
| /// Returns the URL to this user's avatar. | |||
| /// Returns a URL to this user's avatar. | |||
| /// </summary> | |||
| /// <param name="format">The format to return.</param> | |||
| /// <param name="size"> | |||
| /// The size of the image to return in. Image size can be any power of two between 16 and 2048. | |||
| /// The size of the image to return in. This can be any power of two between 16 and 2048. | |||
| /// </param> | |||
| /// <returns> | |||
| /// User's avatar URL. | |||
| @@ -3,7 +3,9 @@ using Model = Discord.API.Attachment; | |||
| namespace Discord | |||
| { | |||
| /// <summary> A Discord attachment. </summary> | |||
| /// <summary> | |||
| /// An attachment file seen in a <see cref="IUserMessage" />. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class Attachment : IAttachment | |||
| { | |||
| @@ -39,7 +41,12 @@ namespace Discord | |||
| model.Width.IsSpecified ? model.Width.Value : (int?)null); | |||
| } | |||
| /// <summary> Returns the filename of the attachment. </summary> | |||
| /// <summary> | |||
| /// Returns the filename of this attachment. | |||
| /// </summary> | |||
| /// <returns> | |||
| /// A string containing the filename of this attachment. | |||
| /// </returns> | |||
| public override string ToString() => Filename; | |||
| private string DebuggerDisplay => $"{Filename} ({Size} bytes)"; | |||
| } | |||